#💻・modding-dev

1 messages · Page 175 of 1

obtuse silo
#

ok i've changed the line to
if SMODS.has_enhancement(context.other_card, 'm_steel') then
but it still ain't working

modern kindle
#

Is there a reference to the 'overscore' or whatever that happens? Like when you reach the blind in a single hand and the fire appears in the ui? I want to reward players for being able to score that much in a single hand, but not just the first hand being noticed, just if they manage to do it in any hand

obtuse silo
#

yea
still nothing

modern kindle
#

did you notice you spelled calculate wrong

#

calcualte = function(self, card, context)

normal crest
#

that'd certainly do it

obtuse silo
#

._.

modern kindle
#

indeed, i was surprised you didnt catch it

normal crest
#

it's the first time i've seen that

#

next time i'll have to look out for misspellings too

obtuse silo
#

it's all a learning process, don't work yourself up about it

modern kindle
#

my stupid ass types stupid so ill often add or swap letters

#

so i always gotta look

#

lmfao

obtuse silo
#

one of my cards is a coffee cup
call that a caculatte

#

calculatte

normal crest
#

i just copy the code for another working joker every time

#

and modify it

modern kindle
#

thats fair, one day i should organize my things and make a localization file too, but i just cant be bothered to

#

everything is in one file

normal crest
#

ew

#

no offense.

#

but that's a horrible habit

modern kindle
#

eh, it works and user has no reason to be in the code so its not really an issue i think

#

the most localization does in my eyes is appearances

normal crest
#

And makes it easier for other people to translate your mod

#

ever since we implemented a loc file in paperback we got a portuguese and french translation

round olive
#

i've never made a mod before do any of u know how I would go about adding my own images over balatro's jokers

modern kindle
#

i find it unlikely for others to use my shit much lmfao
so im not too worried about other languages

normal crest
#

you do you, but i still stand by it being a bad habit

#

like having all your books thrown on the ground instead of a bookcase

modern kindle
#

maybe, either way itll be a bridge i cross later

normal crest
#

context.other_card................

obtuse silo
#

guhhhfhfhhfuhfuifhisdfnilawsfjmiv aewebriuo weihtgnmb wesiuotmb4joswrietpmbjswet

modern kindle
#
  key = "millicent",
  loc_txt = {
      name = "Millicent",
      text = {
          "Played {C:attention}Steel Cards{}",
          "give {C:mult}+#1#{} mult when",
          "scored"
      }
  },
  config = { extra = {mult = 4} },
  blueprint_compat = true,
  rarity = 1,
  atlas = "dilatro",
  pos = {x = 0, y = 0},
  cost = 4,
  loc_vars = function(self, info_queue, card)
      return { vars = { card.ability.extra.mult } }
  end,
  calculate = function(self, card, context)  -- 
      if context.individual and context.cardarea == G.play then
          if SMODS.has_enhancement(context.other_card, 'm_steel') then  
              return {
                  mult = card.ability.extra.mult
              }
          end
      end
  end
}```


this is working when i ran it now
#

change the atlas to yours obv

#

i had to use mine to see

obtuse silo
#

YEAYAYHYHYAH!!

#

I GOT IT WORKING!!!
TY FOR PUTTING UP WITH MY STUPIDITY

modern kindle
#

everybody starts somewhere its all good

dreamy thunder
#

i really gotta seperate my main.lua

vivid solstice
#

just started coding and i have no clue whats going on, im basically just copying the code from SixSuits since im adding 4 more suits and when i checked to see if the first suit would show up in the option this crash came up

#

heres my code this far

normal crest
#

that means you have a syntax error

#

you're mising a comma after lc_ui_atlas = 'ui'

vivid solstice
#

thanks

weak brook
#

trying to make a joker for cardsauce that does negative mult, and it works in calculation but i noticed that if the mult counter goes below 0 it becomes blank. anyone know a mod that has a fix for that?

obtuse silo
#

what's the context for a card being destroyed?
could it literally just be "card_destroyed"?

#

hold on i'm seeing "cards_destroyed" imma go with that

hardy viper
#

destroying_card

royal carbon
#

What happens if two different mods extend the same vanilla-game function in different ways, like the image thinkvi will both execute based on priority or will only the one with higher priority execute

graceful magnet
#

for some reason, after a hand is scored, this isn't resetting or playing the reset message

normal crest
#

G.jokers instead of G.play

normal crest
#

so first based on each mod's specified priority, and then in whatever order the filesystem finds them

#

I believe is how it works

#

and all hooks will apply

frosty dock
#

that's indeed how that works, so long as no one does destructive overrides

#

-# that's if you're not steamodded and aren't lovely patching the override

obtuse silo
#

laughing rn because i thought this would add +4 mult when a card (be it a playing card or Joker) is destroyed
instead
it triggers on each card played and destroys them instead

spring lantern
#

so turns out doing this was super easy

dire palm
#

Is there a way to make my joker change Glass Cards probability to get destroyed, without modifying any other probability?

normal crest
#

as for your desired effect, there's no smods context for destroying jokers, but you can use remove_playing_cards for playing cards, and all the destroyed cards will be in context.removed

obtuse silo
normal crest
#

yes

normal crest
#

what's the exact effect of your joker?

dire palm
#

I want my joker to make it so Glass Cards can’t shatter by themselves.
The Joker will have a 1 in 100 chance to get destroyed at the end of rounds.

scarlet spire
#

trying to make a joker that permanently adds chips to played cards like hiker, what am I doing wrong in this calculate function?

normal crest
normal crest
vivid solstice
#

the game keeps crashing and it shows that "Atlas flip_cards" cannot either find or use the image file for the asset and i dont understand why heres my code and files o show im not going mad

obtuse silo
dire palm
normal crest
normal crest
frosty dock
vivid solstice
#

in my assets folder under 2x since i dont have scaled down versions for 1x (its a long story)

frosty dock
#

you probably have pixel smoothing off?

#

either way you need to have the 1x 🥴

vivid solstice
vale lake
#

does anyone know why it's saying this file doesn't exist when it clearly does?

rough furnace
#

I belive love needs relaitve paths

#

nfs probably has a method to get it

past forge
#

Is there any consumable and booster packs example mod?

#

I mean i could see any mod source code but im looking something easy and beginner friendly

wooden nexus
#

So I'm not sure what's going on with the deck here

#

It's not supposed to have the other ranks in the booster packs

#
        if G.GAME.selected_back and (G.GAME.selected_back.effect.center.key == "b_SCB_AltSuit" or G.GAME.selected_back.effect.center.key == "b_SCB_EveryDeck") then return true end
    end```

I have it as this for in_pool
#

I'm thinking it's something to do with Talisman possibly

#

because I disabled my other mods

vivid solstice
#

when i went to check if the suits were working and was jumpscared with this mess

wooden nexus
#

oh

vivid solstice
past forge
#

you could make it a joker as an easter egg

#

"All aces are considered kings and viceversa"

vivid solstice
spring lantern
#

thoughts? i'm not 100% on the card art but it works for now

torpid delta
#

Been wanting to get into making mods for a while, hoping to get some general help with programming modded jokers mainly, but figuring out how to make card skins (like the Cyberpunk spades) and how to add them to the skin list would be nice to figure out too. All help would be appreciated 🙏

torpid delta
wooden nexus
#

Strange, I can't seem to recreate the bug. I loaded talisman and nothing happened

#

Lemme try re-adding Cryptid

#

It's something with Cryptid

orchid thunder
#

how can i delete a ui box

red osprey
spring lantern
#

oh hi

#

yea that's p much it

#

just gotta make sure you don't play your good cards up`front

past forge
#

I want to thank you

#

Canio's code worked excelent

red osprey
#

Nice to hear

past forge
#

:)

#

how did you got the code that way? the card.lua i have is not that useful

scarlet spire
#

hiker only does the animation once the upgrade message appears on the other card

red osprey
#

So that if you were to add it with SMODS, the resulting code would be what you would put in the calculate

#

And then re-indented it because that's much easier to read like that

past forge
#

okay, ill add learn to do that to my todo list

red osprey
scarlet spire
#

ah, I see, I just looked at what hiker was doing

red osprey
#
return {
  message = localize('k_upgrade_ex'),
  colour = G.C.CHIPS,
  card = context.other_card
}
#

If you're using SMODS this should work too

scarlet spire
#

I mean, it was working already and this works exactly the same

past forge
#

Are there any consumable and booster packs example mod?
I mean i could see any mod source code but im looking something easy and beginner friendly

scarlet spire
#

my issue is that the joker itself isn't doing the animation at the same time like hiker does, only the affected card

red osprey
#

As for juicing up the joker itself at the same time as the message I'm not sure?
I've had similar issues of doing things at the same time as the message, and have a patch that enables an unused feature that allows you to do that

#
# card_eval_status_text()
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = "local extrafunc = nil"
position = "at"
payload = "local extrafunc = extra and extra.extrafunc"
match_indent = true

You can then use extrafunc in the return table like func. It will be executed at the same time the message gets displayed

scarlet spire
#

huh, I see

#

will try this

red osprey
scarlet spire
#

structured like this?

red osprey
#

No

extrafunc = function()
  card:juice_up(0.8, 0.5)
end
scarlet spire
#

oh wait, yeah oops

#

thanks

past forge
#

and changed the messages

scarlet spire
#

wait im blind

#

missing comma

#

works now, thanks!

maiden phoenix
red osprey
#

Cards get destroyed after scoring so you should be fine

#

If "losing your best hand" could be considered fine

maiden phoenix
#

Oh if it's specified to do this then

red osprey
#

All destroy jokers happen after scoring

#

See Sixth Sense (and I assume Alrex implemented it the same way)

hidden timber
past forge
#

YAY!

gilded narwhal
#

preference for these 3 buttons?

#

buttons is the wrong word

#

They're like little pins

faint yacht
vivid solstice
scarlet spire
#

is there a way to just get the number of cards inside G.consumeables (or any other cardarea) or do I just have to loop over them all

gilded narwhal
#

they get applied to every single blind on a certain deck

vivid solstice
chrome prawn
#

is there a way to get the price of shop items like boosters packs such as a value I can use elsewhere?

gusty sequoia
#

Hey, So I used the code from the example joker that gives +4 mult and changed it for chips, it continues to crash when I play a hand with it there, over "Attempt to index field 'vars' [a number value]"
What should I do?

normal crest
#

what does your code look like

gusty sequoia
#

I'll grab it rq

normal crest
#

Based on the error I'd assume you did return { vars = 4 } in loc_vars which is incorrect

#

Or something of that kind

scarlet spire
#

how do I get an enhancement/joker/etc that references something that doesn't exist yet to stop crashing when hovered in the collection if you're on the title screen

#

like, my joker that references the number of consumable cards you have crashes if you hover it on the menu because the consumable area doesn't exist yet, I assume

normal crest
#

set a default value if it doesn't exist

gusty sequoia
normal crest
#

that looks fine

gusty sequoia
#

Hm

#

I wonder why it doesn't work...

normal crest
#

if consumeables exists it'll get the amount of cards, otherwise 0

normal crest
gusty sequoia
#

Well it gave me a different issue this time, so that's nice ig

#

I'll grab the code

#

SMODS.Joker { key = 'PotatoChip', loc_txt ={ name = 'Potato Chip', text = { '{C:chips}+#1#{} Chip' } }, config = { extra = { chips = 21 } }, loc_vars = function(self, info_queue, card) return { vars = { card.ability.extra.chips} } end rarity = 1, atlas = 'Jokers', pos = {x = 0, y = 0}, cost = 0, calculate = function(self, card, context) if context.joker_main then return { chips_mod = card.ability.extra.chips, message = localize { type = 'variable', key = 'a_chips', vars = card.ability.extra.chips } } end end }

#

I wasn't sure what you needed to see, so I just grabbed all of it

normal crest
#

the actual issue here is in your localize call in your return statement

#

vars should be a table

gusty sequoia
#

Ah

normal crest
#

but you don't need to specify the message, just pass chips = card.ability.extra.chips and steamodded will do it for you

gusty sequoia
normal crest
#

same way as in your loc_vars function

#

surrounded by {}

gusty sequoia
#

Thank you so much mate!

scarlet spire
#

it really does not care

#

that should work, shouldn't it

normal crest
#

No

#

because if G.consumeables is nil, it cannot access cards

#

that's why in the example i sent before I did G.consumeables and before

scarlet spire
#

I see

gusty sequoia
#

:D

orchid thunder
#

how can i move a card area

wooden nexus
#

Ayo, what the heck did i do?

modest lake
wooden nexus
#

Still trying to play around with it

primal iron
#

ayo im just getting in to modding this game, is there any way i can get VSCode autocomplete stuff with Steamodded, so i can see the different properties?

wooden nexus
#

It's mostly just the ionized shader but i need to play more to see what happens

modest lake
#

Also uh, new here but I've been trying to add a planet card to the game for a while and it isn't showing up. What exactly do I need for steamodded to add a card? I have already added jokers to the game and can't figure this out. (this is just for me to learn stuff, basing it on cryptid) (Also I know it's cut off, there's just ends and close brackets below the screenshot.)

orchid thunder
#

how to move/remove card areas

placid compass
#

how to use the atlas system?

fallen vigil
#

why isnt it displaying the negative consumable

modest lake
red flower
fallen vigil
#

oh i got it

#

thank you wise one for gracing me with your genius

red flower
#

yw i literally just looked up e_negative_consumable in the game's code

fallen vigil
#

i was just confused because G.P_CENTERS.e_negative works but not when i add consumable

red flower
#

because it's not in P_CENTERS, don't ask me why

fallen vigil
#

ah

red flower
#

rather I think I know why but idk why it's considered an edition in the localization

red flower
native cargo
#

Is there a way to remove a suit from the pool so it doesn't get added to the decks, but allow it to show up in card packs? Or is that a default thing that I'd also have to disable if i wanted it disabled?

modest lake
red flower
graceful magnet
#

is there a way to check how many hands are left?

red flower
#

G.GAME.current_round.hands_left I'm pretty sure

void pecan
#

how does the legendary joker atlas work?
Like I have the back and the joker isolated, but how do I put them together in the code?

graceful magnet
#

soul_pos = {x = yeah, y = sure}

void pecan
graceful magnet
#

yeah

void pecan
# graceful magnet yeah

and final question about it, for x and y do I put the size of a normal card or just the size of the joker?

graceful magnet
#

neither you put the atlas position of it

void pecan
graceful magnet
#

the standalones are essentially just other cards that are being laid on top

modest lake
graceful magnet
gilded narwhal
#

art for one of my decks and its corresponding gimmick

void pecan
modest lake
graceful magnet
#

yes

void pecan
red flower
modest lake
graceful magnet
#

no

void pecan
graceful magnet
#

lua arrays start on a 1 count

modest lake
graceful magnet
#

x = 5, y = 4 is correct

modest lake
red flower
#

atlas starts at 0 as far as I know

modest lake
graceful magnet
#

nope yep I'm wrong this once

#

imagine Balatro coding being consistent

modest lake
#

oh good, I thought I was crazy (which wouldn't be a shock tbh)

void pecan
void pecan
graceful magnet
#

same atlas

void pecan
graceful magnet
#

no

#

it should be on the same image file your other jokers are on, thus you do not need to specify the atlas key again, as you do that to get the Joker sprite anyways

frigid flame
#

does anyone have a list of the fonts used in the balatro jokers?

fallen vigil
#

how do i get the number of spectral cards held in consumable slots

normal crest
#

Loop through G.consumeables.cards, check if <card>.set == "Spectral"

#

may be card.ability.set

wicked spire
#

I don’t need it yet, but do you guys think there’s anyone in here who would be willing to help out with pixel art for card designs if I were to ask for it at a later point?

desert ore
#
        G.E_MANAGER:add_event(Event({
            func = function()
                G.consumeables.config.card_limit = G.consumeables.config.card_limit - card.ability.extra.con_slots
                G.hand:change_size(card.ability.extra.hand_size)
                return true
            end
        }))
        if #G.consumeables.cards > 0 then
            local cards_to_destroy = math.min(2, #G.consumeables.cards)
            G.E_MANAGER:add_event(Event({
                func = function()
                    for i = 1, cards_to_destroy do
                        local destroyed = pseudorandom_element(G.consumeables.cards, pseudoseed('jochinator'))
                        destroyed.T.r = -0.2
                        destroyed:juice_up(0.3, 0.4)
                        destroyed.states.drag.is = true
                        destroyed.children.center.pinch.x = true
                        destroyed:start_dissolve()
                        return true
                    end
                end
            }))
            G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4,
                func = function()
                    play_sound('tarot1')
                    return true
                end
            }))
        end
    end
}```  I'm trying to have an effect where if the joker is destroyed or disabled, it destroys two consumeable cards. I works except for some reason it only ever deletes 1. Before I had the for loop right below local card_to_destroy, but sometimes then it only deleted 1, I assumed it was because the same card was picked twice?
old bane
#

how would i have one atlas come after the other? because i'm adding in a separate atlas for all the legendaries in my mod and they show up before my main atlas in the collection

normal crest
#

The jokers show up in collection in the order you loaded them in your code

#

has nothing to do with atlas

old bane
#

ohhhh wait then i think i know why then

#

it's cause the file comes before the main atlas in alphabetical order

normal crest
#

if you're loading a folder with NFS then yeah

old bane
#

also how would i have it so that a joker gives you +1 discard per round

normal crest
#

A permanent discard or one given at start of blind like burglar

#

"permanent" being for as long as your joker exists ofc

old bane
#

a permanent discard like drunkard i believe

normal crest
#

in your joker, define add_to_deck where you ease_discards(1), on remove_from_deck do ease_discards(-1)

old bane
#

ohh i see okay

#

i had to do a similar thing but for hand size with a juggler joker

orchid thunder
#

so ima ask again does anyone know how to move card areas to off screen

old bane
#

i wonder if I'd be able to delete cards that are held in hand through context.destroy_card 🤔

#

i also don't know the key for jupiter specifically as a card

#

oh wait its c_jupiter

desert ore
modern kindle
# desert ore is the way I'm doing this just not good for what I'm trying to do? I'm taking co...
  key = 'consumeable_destroyer',
  loc_txt = {
    name = 'Reckless Gambler',
    text = {
      "If {C:attention}destroyed{} or {C:attention}disabled{},",
      "{C:red}destroys 2 unique consumable cards{}."
    }
  },
  config = {
    extra = {
      consumeables_destroyed = 2  
    }
  },
  rarity = 3,
  atlas = 'youratlashere',
  pos = { x = 2, y = 1 },
  cost = 7,


  remove_from_deck = function(self, card, from_debuff)
    print("[DEBUG] Reckless Gambler removed. Destroying consumables...")

    local available_consumables = {}
    for _, v in ipairs(G.consumeables.cards) do
        table.insert(available_consumables, v)
    end

    if #available_consumables > 0 then
        local cards_to_destroy = math.min(self.config.extra.consumeables_destroyed, #available_consumables)
        local destroyed_cards = {}

        G.E_MANAGER:add_event(Event({
            func = function()
                for i = 1, cards_to_destroy do
                    if #available_consumables == 0 then break end  


                    local destroyed = pseudorandom_element(available_consumables, pseudoseed('reckless_gambler'))
                    
                    if destroyed then
                        for index, v in ipairs(available_consumables) do
                            if v == destroyed then
                                table.remove(available_consumables, index)
                                break
                            end
                        end

                        table.insert(destroyed_cards, destroyed)
                        print("[DEBUG] Destroying consumable:", destroyed.ability.name)
                        destroyed.T.r = -0.2
                        destroyed:juice_up(0.3, 0.4)
                        destroyed.states.drag.is = true
                        destroyed.children.center.pinch.x = true
                        destroyed:start_dissolve()
                    end
                end
                return true
            end
        }))

        G.E_MANAGER:add_event(Event({
            trigger = 'after',
            delay = 0.4,
            func = function()
                play_sound('tarot1')
                return true
            end
        }))
    end
  end
}

i tested this and this worked for me, at least on sale anyway, youll have to see if it does on debuff

#

it was picking the same one so just making it so it cant pick the same one solves that issue

desert ore
#

this is my first time I'm using lua or any coding at all and i literally just learned how for loops and math.min works, and I don't really understand what ipairs is doing, I saw that in the immolate code and other places

modern kindle
#

ipairs by my understand is to loop over an array, itll return an index and value

so in this case its looping through all consumjables in g.consumeables.cards, then we insert whats available into a table

then we see what was destroyed, return a list, and go for a card that was not destroyed

desert ore
#

ok that makes sense why it's in the immolate code then

#

tysm I'll try to wrap my head around this

modern kindle
#

no worries, just get use to beating your head against the wall in the beginning =]

#

lmk if what i posted works for your desires

fallen vigil
normal crest
#

what does your attempt look like

fallen vigil
spark remnant
#

is there a context similar to end of round but only after the boss blind?

normal crest
normal crest
old bane
#

how would i make it so that each played card gives 1 dollar when scored?

normal crest
#

if context.individual and context.cardarea == G.play then return { dollars = 1 } end

spark remnant
normal crest
#

add and context.main_eval

spark remnant
normal crest
#

are you on the latest steamodded

sick tartan
#

does anyone know what the context card played function is? like I don't know how to do this properly

#

im just trying to add multi whenever a heart card is played ^^

#

I also don't know if the color name is correct because I saw that the example joker had this color and I don't know how to do it for the multi color instead

spark remnant
vital rapids
#

Behold my jonklers

rose dragon
wise crown
#

Ramiel joker???

modern kindle
#

Finally updated my steammodded
Went from 1326a to 1413 good lord they were cruising

coral fjord
vital rapids
vital rapids
#

Would it be great to have all the Evangelion angels as jokers? Yes
Do i want to sprite every Evangelion angel? No

past forge
#

I want to round up the effect of this jonkler, ive seen a function to round up in the wiki but i cant make it work

#

any help on what must i do with the variable that keeps the money taken out to round it up?

plush cove
#

@past forge

past forge
#

thanks

#

okay, its not working

plush cove
#

you can't just use that as a function on its own line

#

you have to use it as a variable

#

card.ability.extra.mult = card.ability.extra.mult + math.ceil(taken_dollars)

past forge
#

is it not a function?

#

okay,, thank you

#

now it works

obtuse silo
#

is there any way to detect when a joker is being destroyed specifically?

past forge
#

if second option, i gues you could use the joker id

obtuse silo
#

besides
the current issue for me is trying to find a way to detect when any cards at all are being removed

#

is remove_from_deck it's own function or do I put it in the calculate function?

past forge
#

This is canios code

plush cove
#

you should probably delete that

past forge
#

it helped me yesterday to make the guillotine joker that i was working on

past forge
plush cove
past forge
#

i mean I have no problem on deleting it but i thought i could post it here

plush cove
past forge
red osprey
#

I think rule 7 more so applies to redistributing the entire source code

#

A lot of modded ressembles vanilla code reshapen slightly

past forge
#

thats what i was thinking

red osprey
#

And things like SMODS directly interact with source code, so discussing it is kinda necessary

red osprey
#

Basically imo, as long as you can't have someone take the code and rezip it into a working Balatro without having to have paid for it, you should be fine

red osprey
# past forge

Also as I told you yesterday you can remove the context.cards_destroyed code

#

It's never triggered in the game

sturdy compass
#

Is it possible to add a second card to the main menu? I'm trying with this but the sorting function is causing a crash for some reason

past forge
red osprey
#

Nothing

#

Keep only the context.remove_playing_cards code

past forge
obtuse silo
#

yeah the code's there to catch shattering glass i think?

red osprey
#

It's never run

obtuse silo
#

mhm

red osprey
#

If you search for "cards_destroyed" in the entire codebase, it's never used inside a context as a flag

#

remove_playing_cards handles glass breaking

obtuse silo
#

ok slight issues
it sort of works
but there's no mult ding when it adds mult to a hand and even when multiple cards are destroyed at once, it only increments by one

red osprey
#

For the latter that's by design

#

It doesn't trigger once for each card, but once for each group of cards being destroyed, so it increments once by the amount of cards destroyed

#

For the former, does it actually add the mult?

red osprey
#

That's odd

obtuse silo
red osprey
#

card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain * destroyedcards

obtuse silo
#

ah

#

thank you

red osprey
#

Replace mult_mod with just mult

#

You shouldn't need a message too

obtuse silo
#

i get efficiency but it works

red osprey
#

You do you

obtuse silo
#

oh wait that's probably why it wasn't registering

#

it automatically does mult, but it doesn't automatically do mult_mod

violet void
red osprey
#

Afaik it was recently added, yeah

wintry solar
#

It does do mult mod it’s just not recommended to use it

red osprey
#

mult_mod is what is used internally, mult is added and handled by SMODS, correct?

obtuse silo
#

that makes a lot of sense

wintry solar
#

Thunk used mult and mult_mod in different calculation steps

red osprey
red osprey
wintry solar
#

So using either now works anywhere, just plain mult does all the auto messaging for you

plush cove
#

does this work?

#

(I am so sorry)

marble flint
#

:(

violet void
red osprey
#

Those returns only add to score. For scaling you need to toy with the ability, and handle the messages yourself

wintry solar
#

I could maybe add support for returning upgrade = true for the standard messaging

plush cove
#

this is the code for one of my scaling jokers

(it scales every time you play a hand with an unscoring card, but it resets if all cards score)

red osprey
#

Neat

plush cove
plush cove
#

you don't have to go in and change a bunch of numbers, you just change one number once

wintry solar
#

Yeah that’s a good habit to get into

red osprey
#

That's the standard way of doing it, even the base game does it

#

And allows more flexibility and compatibility with stuff like whatever Cryptid is doing

wintry solar
#

The base game doesn’t do it for everything iirc

plush cove
#

this is for a joker that activates if you've scored more than 60% already

#

although idk if its entirely necessary to always put it in extra or if I can just put it outside in config

violet void
red osprey
#

Only extra is copied

obtuse silo
#

is there a context for when a hand is levelled up?

red osprey
#

Alongside a few other base values in the config

wintry solar
#

Yeah I believe only certain things in the main config are copied

cerulean rose
#

nope

#

definitely not the case

wintry solar
#

Or saved maybe

plush cove
wintry solar
#

Unless it was changed at some point

red osprey
#

Last time I checked ability was created by cherrypicking things from config, not copied wholesale

#

I can't check the code right now, not at my computer

cerulean rose
#

ive used random keys inside the root config all over strange pencil with no issues

red osprey
#

I followed what the SMODS wiki says on the matter

plush cove
#

i really like how simple it is to add talisman support

obtuse silo
plush cove
random sleet
#

no but you can make one

maiden phoenix
plush cove
maiden phoenix
#

Oh

obtuse silo
random sleet
#

hook/patch the function to call the smods function that calculates a context

violet void
#

the function being SMODS.calculate_context({something = true})

random sleet
red osprey
#

Damn, the Pokermon patches

random sleet
#

exposed for my crimes

rose dragon
#

when compared to other cryptid jokers, is this too powerful for epic or not powerful enough?

plush cove
random sleet
#

it doesnt win the run instantly its too weak

#

also no period at the end

plush cove
#

also make sure to include the "negative" infobox

rose dragon
obtuse silo
#

should be in the Perkeo example code

#

in this file

plush cove
#
    loc_vars = function(self, info_queue, card)
        -- This is the way to add an info_queue, which is extra information about other cards
        -- usually, like Stone Cards on Marble/Stone Jokers, Steel Cards on Steel Joker, and
        -- in this case, information about negative editions on Perkeo.
        info_queue[#info_queue + 1] = G.P_CENTERS.e_negative
    end,```
obtuse silo
#

mhm

plush cove
#

although I still don't exactly know how this works to create unique ones

obtuse silo
random sleet
#

what

#

no this is the hard part theres no helpful anything you're wrangling this nightmare of a codebase to your bidding

obtuse silo
#

oh

random sleet
#

yeah but its really easy

rose dragon
#

thx guys, idk if i should create a pull request cuz this is a bit low effort

plush cove
#

so if you have 2, rather than doing 1.5 x 1.5, it does 3.0 x 3.0

obtuse silo
#

crikey

red osprey
#

Why not push it further and make them retrigger the other copies

plush cove
#

is that truer to the cryptid experience

rose dragon
plush cove
obtuse silo
#

how would i structure it

rose dragon
plush cove
obtuse silo
rose dragon
# plush cove yes!

perhaps retrigger all jokers (mitosis copies) to the right so it doesn't go forever?

red osprey
#

You can filter out the retriggers iirc

rose dragon
red osprey
#

It does mean if you code it wrong, then yes

#

The Mario joker from Cryptid could be one you could look at

random sleet
plush cove
#

since that uses level_up_hand() but negative instead

random sleet
#

yeah

violet void
#

you can check if its positive

random sleet
#

better to have the context be generic and have specific effects check positive/negative

plush cove
#

maybe under the arm, you could do calculate_context({arm_level_down = true})

#

so you can do if context.level_up and not context.arm_level_down

random sleet
#

no like you just pass info about the level up in context.level_up

violet void
#

if you add the new context here you can pass {upgrade_hand = (amount > = 1) } possibly

SMODS.calculate_context(upgrade_hand = (amount > = 1))

And in the joker calc

if context.upgrade_hand then

random sleet
#

like context.level_up.handname, context.level_up.amount etc

obtuse silo
#

i'm sort of mystified rn because the example they use in the examplejokers mod is for Castle

red osprey
#

That's the way all other contexts work

obtuse silo
#

so the igo is the context you want to write in

#

right?

red osprey
#
{
  level_up_hand = true,
  amount = amount,
  hand = hand,
  other_card = card
}
obtuse silo
#
function Game:init_game_object()
    local ret = igo(self)
    ret.current_round.castle2_card = { suit = 'Spades' }
    return ret
end```
(taken from the ExampleJokersMod)
red osprey
#

I'd personally use a patch, I don't have experience with that

obtuse silo
#

i don't have experience with that either-

red osprey
#

Patch a

SMODS.calculate_context({ level_up_hand = true, amount = amount, hand = hand, other_card = card })

at the end of the level_up_hand function

#

You can look into SMODS for inspiration ("lovely" folder). Patches are really simple, they just look for strings inside existing code and either add new code before or after, or replace it entirely

red osprey
#

That is a possibility

plush cove
red osprey
#

Too context dependent

violet void
#

if its easily doable, hooks, otherwise patches

red osprey
#

Some stuff can only be done with hooks, some stuff can only be done with patches (more often the latter)

violet void
#

for me

plush cove
red osprey
#

But yes hooks are probably easier

violet void
marble flint
red osprey
#

Hooks are cleaner when you have multiple mods modifying the same thing, patches might enter conflicts more easily

faint yacht
red osprey
#

Patches are more powerful but more blunt

#

Individually though patches can do anything a hook can do, yes. It's in a wider context that differences show up

violet void
#

hooks can add at the start/end of a function, patches in the middle as well (in short)

plush cove
#

i will probably come to prefer Hooks because I like keeping in my current code and don't like using an entirely separate file and coding format

marble flint
#

hooks can also cause subtle compatibility issues fwiw, depending on the hooks in question

obtuse silo
past forge
#

what does ~= stand for in Lua?

plush cove
past forge
#

because i refuse to think is aproximetaly

past forge
#

thats weird

violet void
past forge
#

why not go for the standard !=

plush cove
#

every other language uses != but lua loves to be unique

marble flint
#

why not go for the standard <> /nj

red osprey
past forge
#

like i think i dont even have that key in this laptop keyboard

red osprey
#

Like triggering a context in this instance

violet void
plush cove
violet void
#

a pain

red osprey
#

The first one is 1-indexing

marble flint
#

not (a == b) my beloved

past forge
red osprey
#

The third is using then/do end and not { }

obtuse silo
violet void
#

the fourth is not having a .contains()

primal robin
red osprey
#

That's what we were discussing

scarlet spire
#

all I dislike is how picky it is with commas

violet void
marble flint
obtuse silo
obtuse silo
#

ah

#

then i run the function?

violet void
#

wdym

#

the function is already being hooked

#

you just do what you want your joker to do

obtuse silo
#

which is... upgrade the hand being upgraded again

violet void
#

well then thats different

#

you can still intercept the function and increase amount by 1 if the joker is held

obtuse silo
#

@_@

violet void
#

Something like this

#

wouldnt need the calculate function in your joker

#

uh typo

plush cove
#

Guys

#

I did it

violet void
frosty dock
obtuse silo
violet void
#

correct

plush cove
#

heya, what's the simplest way to change the colour of the menu? i tried it a few days ago but i couldnt get the thing spinning

#

like the colours were there but the animation just didnt

obtuse silo
# violet void correct

it doesn't work
and
i'd rather it have an animation on the joker to indicate that it is doing something

violet void
#

it doesnt work?

#

I shall test it too

#

I see

obtuse silo
#

i used Pluto and Black Hole to test

#

maybe it's because the code doesn't call the function

plush cove
#

what's your code like?

plush cove
obtuse silo
#

maybe it's because i referred to it as "j_starwish" instead of "starwish"

plush cove
#

you did not add the context

#

you did not add calculate_context

plush cove
obtuse silo
#

rolo's code had it as a comment 😭

violet void
#

because you dont need a calc for that

#

imo

plush cove
#

j_[prefix]_starwish

obtuse silo
#

ok got it

#

ghuhghghghghh

#

i'll deal with this after college

past forge
#

How to get the color of the text depending on the suit?

#

i guess maybe using the same variables

#

are C:diamonds, C:hearts, C:spades and C:clubs valid colors?

violet void
obtuse silo
#

Yuhhh!! thx!!
just send me the code whenever

violet void
#
local original_level_up_hand = level_up_hand
function level_up_hand(card, hand, instant, amount)
    local level_by = amount or 1

    if SMODS.find_card('j_prefix_name')[1] and level_by > 0 then
        card_eval_status_text(SMODS.find_card('j_prefix_name')[1], 'extra', nil, nil, nil, {message = 'Double Upgrade!', colour = G.C.RED})

        level_by = level_by + 1
    end

    original_level_up_hand(card, hand, instant, level_by)
end```

Still no need for the calc function in the Joker itself
past forge
#

Another doubt, how do i make the card randomly select a suit? must I just use localize(G.GAME.current_round.castle_card.suit, 'suits_singular') or the ancient joker suit?

cerulean rose
past forge
#

okay ive just found this

#

lol

obtuse silo
#

should work with Burnt too

violet void
obtuse silo
#

yea i want it to be blueprint compatible

violet void
#

well then youre not done yet

#

I tihnk you need a calc function after all

obtuse silo
#

i'd imagine it'd do a similar ding to how space joker and burnt joker levels up hands
you know
instead of "double upgrade!"
it'd add another level

violet void
#

understandable

#

but that sounds a bit more complicated, you should just use the "amount" the function gives you

#
local original_level_up_hand = level_up_hand
function level_up_hand(card, hand, instant, amount)
    level_by = amount or 1

    SMODS.calculate_context( {upgrade_hand = (level_by > 0)} )

    original_level_up_hand(card, hand, instant, level_by)
end```


```lua
    calculate = function (self, card, context)
        if context.upgrade_hand then
            level_by = level_by + 1

            return {
                card = card,
                message = '+1 Level'
            }
        end
    end

Something like this can work

#

@obtuse silo

prisma loom
#

So, this is supposed to set the enhancement of all cards in hand to Stone cards but I feel Im missing smth here:

#

Nvm I figured it out!

past forge
#

i get this error and i assume it happens when im trying to get the color of the random suit i got

violet void
past forge
#

i see

prisma loom
#

Can someone tell if theres a way to get rid of this wierd visual bug related to stone cards?

#

cards are turning blank for a moment before becoming stone cards

#

that's like very not clean

night pagoda
#

What do you use to turn them into stone? There might be an immediate argument

prisma loom
#

should I just plug it in above func?

night pagoda
#

so remove nil, true

night pagoda
#

(also assuming your order of flipping/unflipping is correct)

#

nice!

prisma loom
#

Thanks kind strangerpeepoLove

violet void
#

a very strong common joker

past forge
#

is not going to be common

dire palm
#

Is there an easy way to identify non-scoring cards?

prisma loom
#

So I wanna make a function that checks how many stone cards in your hand and do X thing per each in hand. Am I doing this correctly?

violet void
#

what do you need it for

prisma loom
#

5$

violet void
#

when?

prisma loom
#

after cards were transformed

#

in one number

prisma loom
# violet void when?

Ive made a code for transforming all cards in your hand into stone cards on use

#

for a spectral card

#

now I need it to identify how many were turned into stone

#

and give 5$ for each transformed

#

in one total sum

violet void
#

is it a different Joker that gives money for each stone card

prisma loom
#

Ive done the first part of the effect

#

now I need to figure out how to make the 2nd

past forge
#

Does this check if hand is or if hand contains?

prisma loom
#

I think it'll be quite complicated for me to make a code which would track which cards were turned into stones and which not

violet void
prisma loom
# violet void whats your consumable code
    object_type = "Consumable",
    set = "Spectral",
    name = "Petrify",
    key = "pertify",
    order = 1,
    cost = 4,
    atlas = "Consumables",
    pos = { x = 3, y = 0 },
    loc_vars = function(self, info_queue, card)
    end,
    can_use = function(self, card)
        return #G.hand.cards > 0
    end,
    use = function(self, card, area, copier)
        local used_consumable = copier or card
        local chosen_card = pseudorandom_element(G.hand.cards, pseudoseed("cry_replica_choice"))
        G.E_MANAGER:add_event(Event({
            trigger = "after",
            delay = 0.4,
            func = function()
                play_sound("tarot1")
                used_consumable:juice_up(0.3, 0.5)
                return true
            end,
        }))
        for i = 1, #G.hand.cards do
            local percent = 1.15 - (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
            G.E_MANAGER:add_event(Event({
                trigger = "after",
                delay = 0.15,
                func = function()
                    G.hand.cards[i]:flip()
                    play_sound("card1", percent)
                    G.hand.cards[i]:juice_up(0.3, 0.3)
                    return true
                end,
            }))
        end

        for i = 1, #G.hand.cards do
            if not G.hand.cards[i].ability.eternal then
                G.E_MANAGER:add_event(Event({
                    func = function()
                        G.hand.cards[i]: set_ability(G.P_CENTERS.m_stone)
                        return true
                    end,
                }))
            end
        end

        for i = 1, #G.hand.cards do
            local percent = 0.85 + (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
            G.E_MANAGER:add_event(Event({
                trigger = "after",
                delay = 0.15,
                func = function()
                    G.hand.cards[i]:flip()
                    play_sound("tarot2", percent, 0.6)
                    G.hand.cards[i]:juice_up(0.3, 0.3)
                    return true
                end,
            }))
        end
        delay(0.5)
    end,
    calculate = function(self, card, context)
            if context.cardarea == G.hand then
                local stones = {}
                for k, v in ipairs(context.cardarea == G.hand) do
                    if v:is_stone() then
                        stones[#stones + 1] = v

}```
violet void
#

can you put it between the code brackets

prisma loom
past forge
#

the code

prisma loom
#

whats the symbol

past forge
#

between 3 of this: `

#

3 at each side

red osprey
#

You can put it between
```lua

```
to format it with syntax highlighting

prisma loom
#

Thanks!

past forge
red osprey
#

Add a variable to count the number of stoned cards
In the second loop, only apply the effect to non-stoned cards and increment that variable
Gain money based on that variable

prisma loom
#

I dont know how

#

to be precise

red osprey
#

You won't need calculate here

prisma loom
red osprey
#

Calculate is used to modify effects/do stuff when other stuff happens. This is a consumeable, so the only thing you should worry about is use

red osprey
#

Probably something like if not G.hand.cards[i].ability.eternal and G.hand.cards[i].ability.name ~= 'm_stone' then

violet void
red osprey
#

Yep, what I described, just without the "already a stone" check

violet void
#

yep they should add that check as well

stiff locust
stiff locust
#

if you want it to be hand is, then you're looking for something like poker hand == "hand name"

#

idk never done it

prisma loom
red osprey
prisma loom
#

ahhh

#

ic ic

red osprey
#

(Not guaranteed to be correct, I recommend you check similar code)

violet void
#

but the real question is why are you checking if playing cards are eternal

stiff locust
#

for the record

red osprey
#

Compatibility I guess?

stiff locust
#

i'm pretty sure it is better to check it with

#

card.config.center == G.P_CENTERS.m_stone rather than card.ability_name == "Stone Card"

#

i don't know why it's better

#

but I was told it is better

red osprey
#

It checks based on a variable rather than a hardcoded value, so it's more robust

stiff locust
#

makes sense

spring lantern
#

havent even finished my first mod and im already brainstorming a second one based on my ocs i think im a bit autistic 😭

prisma loom
red osprey
#

Kim is very similar to Canio, just with built-in destroy
Sasha might be a bit complicated to implement
Otherwise neat, is Zach/Zoey a trans character?

obtuse silo
prisma loom
spring lantern
#

i also somehow forgot canio exists when thinking of kims ability

red osprey
#

You can access it by just unzipping the .exe

prisma loom
#

no I mean like

#

this specific effect

#

or at least something relatively similar

red osprey
#

Iirc you can check the Immolate code, it checks if cards are glass to shatter them instead of dissolving them

prisma loom
#

oh wow

red osprey
#

Or things like Stone Joker which should have a check for Stone cards

violet void
prisma loom
#

lol

#

in terms of code

red osprey
#

That's pretty much what it does, but the destroy code has an explicit check to shatter glass cards

#

Because Glass Joker and visual/sound effects I guess

prisma loom
#

ic ic

#

damn thats tricky to find this stuff

red osprey
#

Ctrl-Shift-F is your friend

#

Or grep

#

Or whatever search tool you have

prisma loom
#

vscode

#

search bar

red osprey
#

Yep

limpid halo
#

Sorry, wasn't able to find much by searching but is there a template repo or getting started guide available somewhere?

red osprey
limpid halo
#

Thank you!

modest lake
#

I've got a pair of UI boxes, is there a way to send a variable output from one to another as an input?

violet void
modest lake
#

This is what I've got going rn

dire palm
past forge
#

How do i concat strings in Lua?

red osprey
#

.. instead of +

past forge
#

okey

red osprey
#

You're also missing )

#

At the end of both prints

wintry solar
past forge
prisma loom
runic pecan
#

Uncommon or Rare?

past forge
#

Uncommon

#

1 in 1000 is just 0.001%

wintry solar
#

No?

red osprey
#

0.1%

wintry solar
#

I think it’s weak even as an uncommon

runic pecan
#

If 1 in 100 instead?

#

What is the rate of Polychrome when the wheel of F hit the 1 in 7?

wintry solar
#

If it hits the 1 in 4 a polychrome is 15%

runic pecan
#

Wait, when did it become 1 in 4?
I thought it was 1 in 7?
Edit: I just checked the wiki, it does say 1 in 4.

cerulean rose
#

refuses to load with StrangeLib 2.0.0

karmic arch
#

Hi chat, I have a question. By default, a negative to played cards gives +1 hand size?

red osprey
#

Yes

karmic arch
#

Thx, I'm going to create jokers on negative cards.

runic pecan
prisma loom
#

use G.hand.cards in brackets?

cerulean rose
#

why in brackets?

wintry solar
prisma loom
wintry solar
#

From a consumable?

prisma loom
#

its a spectral

cerulean rose
#

immolate but bad balatrojoker

wintry solar
#
local converted = 0
for _, handcard in pairs(G.hand.cards) do
  if handcard.config.center_key ~= ‘m_stone’ then
    — set to stone
    converted = converted + 1
  end
end
ease_dollars(converted * 5)
#

Like that

#

But obviously done properly and not types badly on mobile

#

Quotation marks will need changing thanks iOS

cerulean rose
#

you can hold the ' key to get straight apostrophes

#

could've sworn we had a runner emoji

cerulean rose
prisma loom
#

I overcooked this, did I

maiden phoenix
#

You iterate over G.hand.cards twice

manic rune
#

i think you dont need the second for loop in there

#

since the first for loop already does what the second loop does, so its pretty unnecessary

red osprey
#

Remove the outer for loop

#

And move the eternal check inside the second for loop

#

And change G.hand.cards[i] to handcard

manic rune
#
local converted = 0
for i = 1, #G.hand.cards do
  local other_card = G.hand.cards[i]
  if not other_card.ability.eternal and other_card.config.center_key ~= 'm_stone' then
    other_card:set_ability(G.P_CENTERS.m_stone)
    converted = converted + 1
  end
end
ease_dollars(converted * 5)
#

probably that

red osprey
#

This version doesn't increment converted

manic rune
#

oh yeah i forgot

red osprey
#

(Also please indent your code)

manic rune
red osprey
#

You can use tab to add two spaces

manic rune
#

oh actually?

#

ah dang

red osprey
#

And it works for indenting/unindenting multiple lines if you select multiple ones

manic rune
#

thats new

prisma loom
#

What causes cards to instantly transform before flipping?

        local used_consumable = copier or card

        G.E_MANAGER:add_event(Event({
            trigger = "after",
            delay = 0.4,
            func = function()
                play_sound("tarot1")
                used_consumable:juice_up(0.3, 0.5)
                return true
            end,
        }))
        for i = 1, #G.hand.cards do
            local percent = 1.15 - (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
            G.E_MANAGER:add_event(Event({
                trigger = "after",
                delay = 0.15,
                func = function()
                    G.hand.cards[i]:flip()
                    play_sound("card1", percent)
                    G.hand.cards[i]:juice_up(0.3, 0.3)
                    return true
                end,
            }))
        end

        local converted = 0
        for _, handcard in pairs(G.hand.cards) do
            if handcard.config.center_key ~= 'm_stone' and not handcard.ability.eternal then
                handcard:set_ability(G.P_CENTERS.m_stone)
                converted = converted + 1
            end
        end
        ease_dollars(converted * 5)

        for i = 1, #G.hand.cards do
            local percent = 0.85 + (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
            G.E_MANAGER:add_event(Event({
                trigger = "after",
                delay = 0.15,
                func = function()
                    G.hand.cards[i]:flip()
                    play_sound("tarot2", percent, 0.6)
                    G.hand.cards[i]:juice_up(0.3, 0.3)
                    return true
                end,
            }))
        end
    end```
red flower
#

The event occurs after the delay but anything after occurs instantly

wintry solar
manic rune
manic rune
prisma loom
prisma loom
# violet void why?

Well I tested it and it ran only once. I set ease dollars to the turned cards and it was giving me 1$

dire palm
crisp coral
prisma loom
prisma loom
crisp coral
#

yes, the unflipping is the "next" event in this case

prisma loom
violet void
prisma loom
violet void
#

It seems correct, 40$ in total

prisma loom
#

Yeah, it's correct now

violet void
#

5$x8

violet void
#

thats the same thing

#

except not in an event so that might have been it

(ease dollars was not in one so it occurred before the count finished)

violet void
chrome prawn
#

is there a way to get the price of shop items like boosters packs and ect. as a value I can use elsewhere?

red flower
#

the default cost should be in G.P_CENTERS[object_key].cost and the current cost should be in object.cost

this is from the top of my head so it might be wrong

chrome prawn
#

thanks

dire palm
#

Can I make non-scoring cards be added to the scoring hand?

wintry solar
#

Yeah I want to add some actual smods side support for non scoring cards at some point

dire palm
#

So?

prisma loom
#

Im not really sure how to input a delay here

#

if its an event I just use delay = 0.15

#

but what do I do here?

#

@violet void

wintry solar
#

You can do it with some lovey patches but there’s no supported methods for altering them right now, you can look how splash functions and inject into the same place

wintry solar
dire palm
wintry solar
prisma loom
wintry solar
#

And the ease dollars

long sun
#

hihi, how do you check if a card has a particular seal?

#

this code doesn't seem to worklua if context.individual and context.cardarea == G.hand and context.other_card.seal == "Blue" then if context.other_card.debuff then return { message = localize('k_debuffed'), colour = G.C.RED, card = card, } else return { x_mult = card.ability.extra.given_xmult, card = card } end end

prisma loom
long sun
#

if it's the same issue with other_card being garbage-collected i will cry 😭

wintry solar
prisma loom
#

my bad

wintry solar
vivid solstice
#

when i check to see if the added suit works everything does except for the name of the suit being error even though everything looks to be fine whe comparing it to SixSuits

    key = 'Flowers',
    card_key = 'FLOWER',
    hc_atlas = 'cards',
    lc_atlas = 'cards',
    hc_ui_atlas = 'ui',
    lc_ui_atlas = 'ui',
    hc_colour = HEX('d020db'),
    lc_colour = HEX('d020db'),
    pos = { y = 0 },
    ui_pos = { x = 0, y = 0 },
    in_pool = allow_suits
}```
am I missing something?
minor magnet
#

made my best joker yet

minor magnet
prisma loom
#

thanks everyone for helping me out with this onepeepoLove

minor magnet
#

juices up any tarot you hold

#

for example

#

it uses fool? two negative copies of your last tarot

manic rune
#

🗣️

prisma loom
#

thats a ton of work for one effect

violet void
prisma loom
#

wow

minor magnet
#

i'm almost done with all the tarots

#

i need to do strenght and the suit changers

long sun
#

okay fixed it! just had to check for seals in the first place ^^

prisma loom
#

(such complex effects)

minor magnet
#

but buffed

prisma loom
violet void
prisma loom
minor magnet
minor magnet
#

like emperor giving a mega arcana pack instead of just two random cards (still 2 cards, but now you have choice)

manic rune
minor magnet
manic rune
#

nice

minor magnet
violet void
#

could add the respective buffs to the tarots' tooltip

minor magnet
#

mm is there a way to have conditional tooltips?

#

like for them to appear only when you have the scopacane joker

wintry solar
#

Yes

#

Info queue or actual tooltips?

minor magnet
#

ok thats perfect

manic rune
#

is it possible to remove info queue

minor magnet
#

like the extra info they give you

red flower
#

you can put them in a conditional to show/not show them

minor magnet
#

thank you ok great

#

i need to hook all tarots lmao it's gonna take some time

violet void
#

not sure if you need take_ownership to affect vanilla tarots tho

-# if thats even a thing

minor magnet
#

im pretty sure you can edit vanilla tarots

wintry solar
#

You can just inject them

#

If you don’t want to take ownership

#

I’m guessing you already do though for your use effects?

long sun
#

you could create different cards with different art?

#

and then set those cards to never appear in the shop or elsewhere

minor magnet
long sun
#

and then destroy one held tarot, and create one of your new cards

minor magnet
#

mmm you're saying to create a new set altogether

long sun
#

mhm

minor magnet
#

that would make sense

violet void
#

might be too much for one single joker

minor magnet
#

but that would be an insane amount of work

minor magnet
wintry solar
#

Oh I didn’t read the effect properly

dire palm
#

Is it possible to give a card a cost that would be a random value chosen at the start of the run?

vivid solstice
minor magnet
dire palm
#

Does that require a lovely patch?

minor magnet
#

i don't think soù

long sun
#

is there a way a joker can do multiple things?

#

this code doesn't work

if context.joker_main then
      if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
        G.E_MANAGER:add_event(Event({
                    func = function()
            return { mult = card.ability.extra.given_mult }
          end}))
      end
      
      if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
        G.E_MANAGER:add_event(Event({
                    func = function()
            return { x_mult = card.ability.extra.given_xmult }
          end}))
      end
      
      if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
        G.E_MANAGER:add_event(Event({
                    func = function()
            return { chips = card.ability.extra.given_chips }
          end}))
      end
      
      if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
        ease_dollars(card.ability.extra.given_money)
                G.E_MANAGER:add_event(Event({
                    func = function()
            return {
              message = localize('$')..card.ability.extra.given_money,
              colour = G.C.MONEY,
              delay = 0.45, 
              remove = true,
              card = card
            }
                    end,
                }))
      end
    end```
#

(ignore the comma after the third-last end)

minor magnet
timid parrot
#

and you can't return calc from an event

long sun
#

right

#

how would i do that?

#

(keeping the randomness)

timid parrot
#

create a table that you then add entries to using randomness

long sun
#

ooh okay!

timid parrot
#

money might be tougher, you might need a manual evaluation call

#

I'd recommend checking out how other money jokers do it

#

like rough gem

long sun
#

okay so i don't quite get what i'm adding to the table

#

would it be { mult = [...] }?

timid parrot
#

yeah you're just setting the fields but inside your if statements so you can split it up

long sun
#

gotcha ^^

#

thank you!!

timid parrot
#

happy to help

long sun
#

hmm, so Rough Gem does a return

minor magnet
#

anyone knows of any way to add info_queue to base game tarots?

long sun
#

should be grand

timid parrot
#

then try adding it to the table

long sun
#

mhm

violet void
long sun
#

hmm, so the money works, but not the other three

#

new code:

if context.joker_main then
      local outcome = {}
      local index = 1
      if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
        outcome[index] = { mult = card.ability.extra.given_mult}
        index = index + 1
      end
      
      if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
        outcome[index] = { mult = card.ability.extra.given_xmult}
        index = index + 1
      end
      
      if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
        outcome[index] = { mult = card.ability.extra.given_chips}
        index = index + 1
      end
      
      if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
        ease_dollars(card.ability.extra.given_money)
        G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + card.ability.extra.given_money
        G.E_MANAGER:add_event(Event({func = (function() G.GAME.dollar_buffer = 0; return true end)}))
        outcome[index] = { dollars = G.GAME.dollar_buffer }
        index = index + 1
      end

      return outcome

    end```
red osprey
#

Don't put them in an array, put them all in the same table

long sun
#

do i need to add card = card?

#

ah

#

no clue how to do that in lua, two seconds =w=

tepid crow
#

you're creating a table that looks like this

outcome = {
  [1] = {mult = ...},
  [2] = {mult = ...},
  [3] = {dollars = ...},
}
red osprey
#
outcome = {}
outcome.mult = card.ability.extra.given_mult
outcome.Xmult = card.ability.extra.given_xmult
outcome.chips = card.ability.extra.given_chips
outcome.dollars = card.ability.extra.given_money
manic rune
red osprey
#

The rest should be handled by SMODS, in particular messages and easing

long sun
#

ohhhhh i see!!

#

cheers ^^

#

i had no idea that was possible :}

red osprey
#

Lua is extremely permissive

long sun
#

^^^ strongly typed programmer

red osprey
#

Also arrays and tables are technically the same object like in JS

manic rune
#

made a function to clean up a string

red osprey
#

But to an even more extreme degree

urban veldt
#

Is there a proper modding tutorial?

#

I have no clue what I'm doing lmao

tepid crow
#

just tables in a trench coat

red osprey
#

It technically doesn't

#

Just tables with number keys

tepid crow
#

exactly lmao

long sun
#

bingo! it works now ^^

#

thanks!!

red osprey
#

(And nothing prevents you from having one with both string and number keys)

#

(Which gets fun on whether you use ipairs or pairs to iterate it)

tepid crow
#

"would you like to shoot yourself in the foot" speedrun edition

red osprey
#

Lua is definitely not my favorite language

#

But it works

#

And it's popular thanks to that permissivity

#

And the fact it's, at the end of the day, fairly easy to learn and doesn't have that many advanced stuff in it
Once you get metatables you basically have hit the skill ceiling of Lua in terms of language knowledge

manic rune
#

imagine if someone can make c++ compatible with balatro somehow lol

minor magnet
#

where do i put lovely patches?

manic rune
#

then put it there

tepid crow
#

either lovely/<name>.toml or lovely.toml

violet void
manic rune
#

oh i see

wintry solar
#

You can definitely take ownership of a tarot

violet void
#

@minor magnet

minor magnet
#

it seems intuitive you could do it but it doesn't seem to work

wintry solar
#

Show code

minor magnet
#

used stone as a test since i havent made custom info_queues yet

red osprey
#

Put the table in the parentheses

#

take_ownership('c_fool', { ... })

wintry solar
#

I think the key should be a string too

red osprey
#

Good catch

violet void
#

a question I have about taking ownership, what happens if multiple mods do that for the same item

minor magnet
#

life savers

wintry solar
#

Priority will determine the order

violet void
wintry solar
#

All of them

violet void
#

interesting

red osprey
#

But later ones might override values define by previous ones

#

Like loc_vars in this case

#

Would calling the original function help against this?