#💻・modding-dev

1 messages · Page 195 of 1

humble girder
#

to be fair aure redid card art stuff today, wouldn't be unreasonable that it happened today

#

but yeah it's vanilla

maiden river
#

got it
had to make a lovely patch

wintry solar
humble girder
#

oh it's not merged yet

#

rip

wintry solar
old bane
#

why are stickers so tiny >_<

stiff locust
#

how do I redeem a voucher from a joker

zealous glen
#

idk Betmma

#

see* Betmma

wintry solar
#

You make the card and then use redeem on it iirc

stiff locust
#

i tried looking at the code for like housing choice and idk if its just the way betmma codes

#

i cant understand it

tall wharf
autumn coral
#

is there a template shader somewhere to start off with as a starting ground for all other shaders?

#

all of the resources are cool and all but they are not helpful at all if you have no idea wtf you're doing like me LMAO

autumn coral
#

oh i guess i see one

tall wharf
#

ok works

modern wigeon
#

Oops! The game crashed:
functions/common_events.lua:2486: attempt to compare nil with number

Additional Context:
Balatro Version: 1.0.1o-FULL
Modded Version: 1.0.0~ALPHA-1424a-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.7.1
Platform: Windows
Steamodded Mods:
1: Betmma Voucher Pack by Betmma, nicholassam6425 [ID: BetmmaVoucherPack]
2: Handy by SleepyG11 [ID: Handy, Version: 1.3.2, Uses Lovely]
3: 5 legendary challenges by Betmma [ID: legendaryChallenges]
4: Betmma Vouchers by Betmma [ID: BetmmaVouchers, Priority: -1, Version: 3.0.1(20250129)]
5: Neato Jokers by Neato [ID: Neato_Jokers, Version: 1.0.3, Uses Lovely]
6: Sonic the Hedgehog Deck by SeagullMoe [ID: sonic_deckall, Version: 1.0.0]
7: Better Vouchers This Run UI by Betmma [ID: BetterVouchersThisRunUI]
8: JokerDisplay by nh6574 [ID: JokerDisplay, Priority: -100000, Version: 1.8.2]
Lovely Mods:
1: betmma_mods
2: Saturn-alpha-0.2.1-A

Stack Traceback

(3) Lua global 'calculate_reroll_cost' at file 'functions/common_events.lua:2486'
Local variables:
skip_increment = boolean: true
(*temporary) = nil
(*temporary) = number: 0
(*temporary) = table: 0x3e3a82c8 {click_offset:table: 0x3e2dbb80, children:table: 0x3dea0688, ambient_tilt:0.2 (more...)}

humble girder
#

just stop comparing nils with numbers people jeez

modern wigeon
#

(*temporary) = string: "attempt to compare nil with number"
(4) Lua field 'func' at file 'functions/state_events.lua:258'
(5) Lua method 'handle' at file 'engine/event.lua:99'
Local variables:
self = table: 0x3e7a6a48 {start_timer:true, timer:TOTAL, blockable:true, trigger:immediate, func:function: 0x3df3e2a8 (more...)}
_results = table: 0x3e42c4e8 {blocking:true, pause_skip:false, time_done:false, completed:false}
(6) Lua method 'update' at file 'engine/event.lua:182'
Local variables:
self = table: 0x3df48a68 {queue_last_processed:67.933333333331, queues:table: 0x3df48a90, queue_dt:0.016666666666667 (more...)}
dt = number: 0.00395352
forced = nil
(for generator) = C function: next
(for state) = table: 0x3df48a90 {unlock:table: 0x3deeb428, other:table: 0x3deeb4c8, tutorial:table: 0x3deeb478 (more...)}
(for control) = number: nan
k = string: "base"
v = table: 0x3deeb450 {1:table: 0x3e3360c8, 2:table: 0x3e7a6a48, 3:table: 0x3decd040, 4:table: 0x3ebf27a0 (more...)}
blocked = boolean: false
i = number: 2
results = table: 0x3e42c4e8 {blocking:true, pause_skip:false, time_done:false, completed:false}
(7) Lua upvalue 'gameUpdateRef' at file 'game.lua:2566'
Local variables:
self = table: 0x3dce49a8 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x3e856c30 (more...)}
dt = number: 0.00395352
http_resp = nil
(8) Lua upvalue 'gameUpdateRef' at Steamodded file 'src/ui.lua:84'
Local variables:
self = table: 0x3dce49a8 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x3e856c30 (more...)}
dt = number: 0.00395352
(9) Lua method 'update' at line 22 of chunk '"11585"]'

#

Local variables:
self = table: 0x3dce49a8 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x3e856c30 (more...)}
dt = number: 0.00395352
(10) Lua upvalue 'love_update_ref' at file 'main.lua:992'
Local variables:
dt = number: 0.00395352
(11) Lua field 'update' at file 'main.lua:3129'
Local variables:
dt = number: 0.00395352
(12) Lua function '?' at file 'main.lua:931' (best guess)
(13) global C function 'xpcall'
(14) LÖVE function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '?' (defined at line 902 of chunk main.lua)
inerror = boolean: true
deferErrhand = Lua function '(LÖVE Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(LÖVE Function)' (defined at line 355 of chunk [love "boot.lua"])

humble girder
#

MR PRESIDENT GET DOWN

modern wigeon
#

Needing some help with this please-

#

I clicked the button for the next round and it showed me... That-

humble girder
#

first, turn off every mod that isn't the one that's crashing

modern wigeon
#

How do I know which one isn't crashing?

grim remnant
#

(sorry for the delay, uh, things happened) uhhh, how exactly does main_end work? like, how do we call it in the actual card text, let alone make it so it won't show up if the config setting is disabled?

hardy viper
#

turn half of them off, if it's still crashing (the same way) then none of the mods you just turned off are the problem

modern wigeon
#

I turned half of them off and the game crashed the second I clicked play LMAO

random sleet
#

progress

rough furnace
#

what if I went and actually finilized the meta tags pr

random sleet
#

please save me from this hell

humble girder
#

i would never say no to debugplus debugging harder

rough furnace
#

but I don't want to touch the hundreds of tags to make sure they make sense

wintry solar
#

How far off is it?

rough furnace
random sleet
#

(if it could also work for enhancements that'd be swell)

rough furnace
#

but there were some weird choices I needed to redo

#

the plan was that it would eventually work for all object types

#

I should finish this so I can use it in JamMod

random sleet
#

(Gappie did not draw this card)

wintry solar
#

Gappie draws every card

random sleet
#

sometimes modding this game is just "hey i can do this thing" asHeart

prisma loom
prisma loom
#

It would be a nice feature

#

Same for tags

rough furnace
#

3 will put a voucher in the shop (if your in the shop)

#

also 3 and c should work in tags

prisma loom
wintry solar
#

You can hover it and type eval dp.hovered:redeem() too

#

This might crash calc though I am unsure

rough furnace
#

dp.hovered my beloved

wintry solar
#

It’s great

#

I love using it when watching shaders to change the preview card

grim remnant
#

okay, this is a stupid as hell question. how exactly do we refer to the config? this crashes on line 18, so there's no doubt that it's an issue with that if statement.

rough furnace
wintry solar
#

Does that live update?

rough furnace
#

no

#

cause it reopens the gui

#

I was thinking adding more jokers to the preview with like 4 set and the 4 random

#

maybe I should add some way to set what the watched joker is

wintry solar
#

Yeah I’d like that

#

Just a key in the end of the command would work right?

rough furnace
#

uhhh the command wasn't really made for that

#

especially since I don't have a good way to include spaces in options

#

I need to make a better command parser sometime

grim remnant
#

still stuck on this. any idea what we're missing here??

bold sleet
#

can we see the config file_

zealous glen
grim remnant
#

we've been wanting to rename setting_1 internally but given it just straight up isn't working right now that'll have to wait

normal crest
#

you have syntax errors once more

#

you added brackets to the if statement

old bane
#

i wonder if in context.game_over , i can make it so that instead of just skipping to the next round as if you won, i can instead give the player extra hands to work with 🤔

bold sleet
#

-# oh, i see them now. damm i am stupid

wintry solar
#

You’d have to do some funky work in context.after I think

bold sleet
#

There is some tweaking to be done, but here is the base conditional.

#

You can change context.joker_main to whatever the fuck you need.

tall wharf
#

sorry jimbo

old bane
grim remnant
#

we've removed the brackets yet now it's complaining about the lack of a "then" that should be there, unless for some reason the "if" statement just isn't counting it??? we're still not even sure if we're calling the config file correctly honestly.

bold sleet
#
can_use = function(self, card)
  if G.GAME.current_round.hands_left == 0 then -- not tested. You probably want to set this to 1 instead of 0 because I don't think you can use consumables while stuff is taking place.
    return true
  else
    return false
end
#

@old bane

normal crest
#

If your hands are at 0 the round kinda just ended, so you can't use it

normal crest
#

also return G.GAME.current_round.hands_left == 0

normal crest
bold sleet
#

So use 1 instead of 0

timid parrot
# tall wharf

Maybe add a 3x3 R at the end of “Joke” to keep the convention of hiding “Joker” in every joker card

timid parrot
#

Ah

#

That works

tepid eagle
#

if jimbo wore pants would he wear them like this or like this

bold sleet
#

Hello, I know this is a bit of a broad question, but how does the info_queue thing work? Like, how do you add stuff to it? And how do you make said stuff?

bold sleet
random sleet
#

the hubris to think that jimbo's true form could ever be known

fathom thunder
# tall wharf

i would say insane ball knowledge but like its probably really well known anyway just not mentioned as much anymore

tall wharf
#

it's kinda direct continuation of the previous thing i drew

fathom thunder
#

ah

tall wharf
fathom thunder
#

LMAO

tall wharf
#

I'm sorry

fathom thunder
#

this is so peak

bold sleet
#

It is forbidden to be debuffed and do nothing

tall wharf
#

card gets debuffed forever

bold sleet
#

lol

bold sleet
#

(the shit that adds any edition's text to cards and shit)

tall wharf
#

this is so stupid

bold sleet
#

Where tf are you finding those?

tall wharf
#

these are like

#

old r/Engrish stuff

rough furnace
random sleet
#

thats a fox

grim remnant
#

this is an excruciatingly stupid question. discovered part of the issue was that the config page itself we set up last night was broken. how do we... how do we make it actually modify the config file?

like, the actual answer seems obvious, it's an issue with ref_table, but getting there is a whole different story and trying to work our way backwards with talisman as a reference point has us clarifying stuff like local lovely = require("lovely") that not only just spawn even more issues, but we're fairly confident those are by no means necessary.

rough furnace
#

SMODS.current_mod is only avaible during your mod loading

#

you can save the object in a table or reference it by ID with SMODS.Mods.Id

grim remnant
#

oh, we were actually fairly close it turns out!

#

the only thing now is that the actual text formatting uh, doesn't appear in the resulting strings. how do we resolve that?

rough furnace
novel violet
#

hey gang - is there a good way to use pseudorandom to simply generate a random number between X and Y? i'm aware that it generates a random number between 0 and 1, which is fantastic for probabilities, but what i'm wanting to do is have it randomly generate a number to pull from a value in an array, which isn't necessarily probability
or is there another function that could be used for this sort of implementation that integrates with the game's RNG

random sleet
#

pseudorandom_element is exactly what you want

novel violet
#

oh fantastic, thank you! based on context i'm seeing in smods code i'm assuming the format is something like array/pool size and seed val

grim remnant
random sleet
#

you give it the table

novel violet
#

say i threw the name of an array i created in "pool," would that be compatible

random sleet
old bane
#

how do i declare a new consumable type in both the collection and the labels localization entries

novel violet
#

so for example, pseudorandom_element(FiveStarChars, pseudoseed('intertwined')) would generate a value from 1 to 2?

random sleet
#

it would generate "keqing" or "placeholder"

novel violet
#

OOOO actually that makes my life a lot easier

#

that is incredibly intuitive - thank you!

tall wharf
novel violet
#

coming from only having known c++ i am continually shocked by how intuitive lua stuff is 😭

novel violet
random sleet
#

pseudorandom and its derivatives are thunk's code

tall wharf
#

so no 50/50 either

random sleet
#

or like a framework he's used

rough furnace
#

I think it's origianl thunk code

edgy reef
#

🔥 🔥 🔥

novel violet
# tall wharf so no 50/50 either

so to make things less complex and redundant, i'm making it to where Intertwined Fate jokers show up in the shop as Rare and always give you a random 5-Star, but Acquaint Fate jokers (Uncommon) give you a 4-Star

#

no pity, no actual limited stuff, very much unlike the actual game

#

reimplementing genshin's gacha mechanics to the letter in balatro would be extremely unfun for the player, so i'm not doing that xP

random sleet
#

great news i dont think the new update breaks anything (so far) 🎉

zealous glen
#

Hold on someone give Jimbo a crowbar

edgy reef
#

All it did besides adding new collabs is reworking the credits UI

tepid crow
#

friends of jimbo usually don't break stuff

#

luckily

tepid crow
minor magnet
#

too strong?

novel violet
#

probably tbh

minor magnet
#

would X0.25 be better?

novel violet
#

i'd recommend like x.25 yeah

zealous glen
novel violet
#

absolutely insane joker

zealous glen
#

and art

novel violet
#

yeah i agree, i love that

tall wharf
#

lovely art

grim remnant
tall wharf
#

ok guys if that's a legendary then what the hell do i do with eat pants

zealous glen
#

depends

zealous glen
novel violet
tall wharf
#

scored

novel violet
#

oh right

tall wharf
#

i wanted to make it destroy all played cards but I'm stupid

novel violet
#

i mean still. either way. that is insane

hardy viper
#

no celeste 💔

tepid crow
#

how could they 😩

tall wharf
#

so

#

do i just mark every card in hand for destroying

foggy carbon
novel violet
#

inscryption cards could go insane

hardy viper
#

i asked maddy and she barely acknowledged it so i think ill just die

zealous glen
tall wharf
#

don't want it to be legendary 😭

novel violet
#

quite honestly i'm just devastated that bugsnax was assigned to hearts. now me and my buddy have to choose between isaac and bugsnax

minor magnet
hardy viper
#

balatronically 😭

tall wharf
#

eat pants being legendary is funny but i don't like it 😭

novel violet
#

it can just be rare

#

i see nothing wrong w/ that

foggy carbon
tepid crow
tall wharf
#

i feel like there's a better way than

[[patches]]
[patches.pattern]
target = '''=[SMODS _ "src/utils.lua"]'''
pattern = '''            card_eval_status_text(card, 'debuff')'''
position = "after"
payload = '''
SMODS.score_card(card, context)
'''
match_indent = true
novel violet
#

honestly just being able to use any collab on any suit would be fantastic

tall wharf
#

calculating the card even if it's debuffed but only if the joker wants to

minor magnet
#

how do i have the joker return a message after gold cards score?

#

i mean

#

pay out

#

not score

grim remnant
zealous glen
foggy carbon
zealous glen
novel violet
#

i am looking forward to it owo

minor magnet
#

but it returns the message before the effect actually happens

grim remnant
tepid crow
ivory coral
#

hello chat, i have an issue, im trying to make this joker retrigger played cards when played hand contains a flush, but its instead triggering on every poker hand including flush, like high card and pair, whats wrong with the code?

        if context.repetition and context.cardarea == G.play and context.poker_hands['Flush'] then --if played hand contains a flush
            return {
                repetitions = card.ability.extra.repetitions, --retrigger cards
                message = localize('k_again_ex'),
                card = card
            }
        end --im not actually 100% sure this works its a bit buggy
    end```
grim remnant
#

we are absolutely not calling main_end correctly nor do we know how exactly to set it. what're we doing wrong here?

zealous glen
#

and the function code is defined per Joker (or maybe imported from a file if it's shared)

#

here's an example:

#

(technically that video is outdated with the code)

grim remnant
#

the idea is that the text will change based on if config.showOrigin == true, either displaying a string specified by the loc_txt if it's true or just hiding it altogether if it's false. this text has two formats; {c:inactive,s:0.8} if true, and if false, {s:0.0}. we got tantalizingly close with a non-main_end, variable-based approach, but it couldn't display the text formatting correctly.

grim remnant
zealous glen
#

if you do want to show it, then you return the actual text as a node

maiden phoenix
zealous glen
#

I can send you a generate_main_end as an example

frosty dock
#

main_end seems overkill for this when you can just have two separate localization entries

zealous glen
#

I think accessing the second localization inside main_end is easier than changing which one the Joker uses

#

you end up with two localization entries either way

frosty dock
#

fair enough

grim remnant
old bane
#

how would i make a consumable that can only be used while inside a blind?

tepid crow
old bane
#

so like

can_use = function(self, card)
  if G.game.blind then return true
  else return false
  end
end
tepid crow
#

if G.game.blind is the proper way to check if the player is in a blind, then yes

old bane
#

oh wait it's G.GAME.blind.in_blind

frosty dock
#

G.GAME.blind.in_blind

old bane
#

blind in blind

grim remnant
old bane
frosty dock
grim remnant
grim remnant
humble girder
#

do shaders support additional textures

#

wow that question ended up being so far less specific than I wanted it to be

zealous glen
rough furnace
frosty dock
# grim remnant at this point, we were clarifying it in the loc_vars of the card code itself, th...

You can't have a loc_vars in your localization file. I'd be looking at something like this for the joker's loc_vars

loc_vars = function(self, info_queue, card)
  local t = { vars = { blah } }
  if config.showOrigin then t.key = self.key..'_source' end
  return t
end

and a setup as follows in your loc file

j_stla_paulJoker = {
  name = 'Paul',
  text = {
    '{C:chips}whatever else',
    'Paul.',
  }
},
j_stla_paulJoker_source = {
  name = 'Paul',
  text = {
    '{C:chips}whatever else',
    'Paul.',
    '{C:inactive,s:0.8}Origin: Paul',
  }
},
zealous glen
#

I haven't tried it but I want to sometime

humble girder
#

I was hoping there was any smods support for it

#

I definitely don't want to go back to raw opengl

rough furnace
#

what are you trying to do?

frosty dock
#

if you have an additional texture, you can draw the shader on it separately i guess?

humble girder
#

nah, I need a noise texture

frosty dock
#

it's hard to tell what you need when you're being so specific

humble girder
#

preferably one I'm not generating with math

#

yeah I dunno what's wrong with me rn I can't words like at all

#

basically, making an edition, need a pre-baked noise texture to be available in the shader

frosty dock
#

I don't shader, so i don't think my input would be of use

humble girder
#

welp, it's 10:46 PM i'm sure i have it in me to learn low level LÖVE GL stuff

zealous glen
humble girder
#

that's not really going to help alone, that can be used to pass the texture id but it still has to be loaded

zealous glen
zealous glen
humble girder
#

yes that's precisely what i'm going to figure out as soon as my attention span wanders over from discord to vscode

#

oh boy

zealous glen
#

I think the only difference is that it's an extra variable

humble girder
#

i'm looking at love

zealous glen
#

Don't look at love look at hatred

humble girder
#

i don't think there's support for loading two textures into one shader pass

zealous glen
#

There is you just pass multiple textures to the shader

humble girder
#

listen

#

show me an example

#

and i'll believe you

#

until then i'm believing the documentation

humble girder
#

cheers

#

you probably just saved me like 30 minutes

zealous glen
#

If you do it so I can copy it you'll save me 2 weeks

humble girder
#

deal, probably

old bane
#

how does a glass card draw its shader

frosty dock
vapid cloak
#

hey if im using neato jokers as a reference is that ok?? like if i'm looking at their code and trying to create my own jokers by learning from it

old bane
frosty dock
#

just the base dissolve shader on the sprite

#

nothing else is special about glass cards being drawn, their sprite just has some transparency

paper zealot
vapid cloak
#

yeah thats what im attempting to do lol

tall tangle
#

That's... That's called learning...

foggy carbon
#

I asked last night but chat was kinda dead.
What order does context.before vs. boss blind debuffs happen? If I want something to happen before the debuff, is context.before enough

paper zealot
#

I was going to try and link to a Joker pack released under an open license that you could just copy from (with credit), but I actually can't find any

tall tangle
# tall tangle That's... That's called learning...

Like... That's literally how plane geometry is taught. You look at things, figure out how they work, then take what you've learned from how some things work to figure out how other things work. Proofs, theorems, corollaries, it's all going based on what someone else has done, and learning from it.

#

As stated, don't just copy things and claim it as your own, but you can analyze how something is built to figure out how to build other things. That's architecture. That's development. That's learning.

#

Hell, that's how the legal world works. Precedent and all that.

west mason
#

is there a way to make copies of the same joker have different values?

tall tangle
#

Every Monster you get increases the xMult of future copies of Monster.

humble girder
# zealous glen If you do it so I can copy it you'll save me 2 weeks

so what I did was basically create an Image object based on Atlas, ripping out the things we don't need from an atlas:

BALIATRO.Images = {}

BALIATRO.Image = SMODS.GameObject:extend {
    obj_table = BALIATRO.Images,
    obj_buffer = {},
    required_params = {
        'key',
        'path',
    },
    set = 'Image',

    register = function(self)
        if self.registered then
            sendWarnMessage(('Detected duplicate register call on object %s'):format(self.key), self.set)
            return
        end
        self.name = self.key
        BALIATRO.Image.super.register(self)
    end,

    inject = function(self)
        local file_path = self.path
        self.full_path = (self.mod and self.mod.path or SMODS.path) ..
            'assets/images/' .. file_path
        local file_data = assert(NFS.newFileData(self.full_path),
            ('Failed to collect file data for Image %s'):format(self.key))
        self.image_data = assert(love.image.newImageData(file_data),
            ('Failed to initialize image data for Image %s'):format(self.key))
        self.image = love.graphics.newImage(self.image_data,
            { mipmaps = true, dpiscale = G.SETTINGS.GRAPHICS.texture_scaling })
        local mipmap_level = SMODS.config.graphics_mipmap_level_options[SMODS.config.graphics_mipmap_level]
        if not self.disable_mipmap and mipmap_level and mipmap_level > 0 then
            self.image:setMipmapFilter('linear', mipmap_level)
        end
    end,
}

Now self.image of an image object holds a lovely image. According to the forum post this can be sent as a uniform sampler2D

BALIATRO.Image {
    key = 'test_noise',
    path = 'test_noise.png'
}

SMODS.Shader {
    key = 'test',
    path = 'test.fs',

    send_vars = function(sprite, card)
        return {noiseTex = BALIATRO.Images['test_noise'].image}
    end,
}```

And it should be then accessible through an uniform/extern in the shader:

extern Image noiseTex;

tall tangle
#

Probably a mechanic you can use as a basis.

humble girder
#

this is as far as I got, and then I stopped because in the meantime I found a suitable mathematical noise algorithm

#

but as far as I understand everything this should work in theory

tall tangle
#

🎶 nothing can go wrong 🎵
"Oops, the game crashed!"
OH, NO, IT ALL WENT WRONG

quasi comet
#

I'm making something that halves a current blind's chips; it works but I can't seem to update the chip count in the blind

humble girder
#

you have to update the number and rerender it

#

look at what happens when Blind:disable() hits The Wall

quasi comet
#

lemme check that

foggy carbon
quasi comet
#

oh, i had it right, just messed up a part of the formatting lol

#

thanks!

tall tangle
# quasi comet lemme check that

Another thing you can look at is Braille Joker from either BBBalatro or Cheesy Jokers (can't remember which), which reduces blind size by 25%

quasi comet
#

No worries, I got it working :) But thank you

tall tangle
#

No problem

humble girder
#

¯_(ツ)_/¯

#

feel free if you want to

old bane
#

i'm trying to make it so that an enhanced card sprite will shrink down to the size of a regular card, but instead i just have comically large cards >_<

west mason
# tall tangle Cryptid Monster joker does that

yeah i already have something like that at work, what i need is for 2 or more copies of the same joker to have different values there. Right now if i spawn multiple copies they all have the same value

unkempt thicket
#

How can I manipulate a sprites rotation, position, scale, etc.? (and its layers)

stable agate
#

Trying to have a card's description change based on suit. It's saying there's an error at line 533 indexing a nil value, but G.GAME.current_round.dizzy_card.suit shouldn't be a nil value since it's called in calculate. I also provided my localization file. Any idea what spits this error?

paper zealot
tepid crow
#

can someone explain wtf thunk meant by this

if not first or first then
paper zealot
# stable agate Trying to have a card's description change based on suit. It's saying there's an...

I think you have to add the parameter to loc_vars and fix your localise arguments:

return {
    vars = {
        G.GAME.probabilities.normal, self.abilities.extra, G.C.SUITS[G.GAME.current_round.dizzy_card.suit], localize(G.GAME.current_round.dizzy_card.suit, 'suits_singular')
    }
}`
and then in your `en-us`:
```lua
`name = "Dizzy Joker",
text = "This joker has a {C:green}#1# in #2#{} chance",
" to create a {C:spectral}Spectral{} card whenever",
"A card of {V:3}#4#{} suit is scored",
"Suit changes every round.",
stable agate
# paper zealot I think you have to add the parameter to `loc_vars` and fix your localise argume...

Does current_round.x_card.suit have to be put in local vars or extra? I tried making sure the joker worked by default (without the localize files), and I'm getting an index nil value error around this line if (context.other_card:is_suit(G.GAME.current_round.dizzy_card.suit)) and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit and (pseudorandom('dizzy') < G.GAME.probabilities.normal/card.ability.extra) then for the current round suit

paper zealot
#

Neither, i think that will need to be a member of the card directly if you want to access it like that

#

But if you add it to extra then you can access it with G.GAME.current_round.dizzy_card.extra.suit easily

stable agate
#

so add current round suit to the extra line?

old bane
#

how would i use tobig() with G.GAME.chips? is it just
tobig(G.GAME.chips)? i'm running issues with talisman and a mr.bones-like joker

paper zealot
#

This will also require you to change the loc_vars function again to use extra.odds instead of just extra

stable agate
#

I'll see if this works

frosty dock
#

depends on what you're using it for, too

#

most of what you need to use to_big for are comparisons

stable agate
# paper zealot To be more specific, add it as a named member of the extra table: `config = { ex...

Here's the code from "config" to as far as discord would let me I'm still getting a nil value around the line I sent before (the line containing if context.othercard:is_suit)

    loc_vars = function(self, info_queue, card)
        return { vars = {
            G.GAME.probabilities.normal,
            self.abilities.extra.odds,
            localize(G.GAME.current_round.dizzy_card.suit, 'suits_singular'),
            colours = { G.C.SUITS[G.GAME.current_round.dizzy_card.suit] }
                        }
        }
    end,
    calculate = function(self, card, context)
        if context.individual and context.cardarea == G.play then
            if (context.other_card:is_suit(G.GAME.current_round.dizzy_card.suit)) and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit and (pseudorandom('dizzy') < G.GAME.probabilities.normal/card.ability.extra) then
            G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
            return {
                extra = {focus = self, message = localize('k_plus_spectral'), func = function()
                    G.E_MANAGER:add_event(Event({
                        trigger = 'before',
                        delay = 0.0,
                        func = (function()
                                local card = create_card('Spectral',G.consumeables, nil, nil, nil, nil, nil, 'dizzy')
                                card:add_to_deck()
                                G.consumeables:emplace(card)
                                G.GAME.consumeable_buffer = 0
                            return true
                        end)}))
                end},
                colour = G.C.SECONDARY_SET.Spectral,
                card = card
            }
        end
    end
end
}

local igo = Game.init_game_object
function Game:init_game_object()
    local ret = igo(self)
    ret.current_round.dizzy_card = { suit = 'Spades' }
    return ret
end```
old bane
#

i just need it for division

foggy carbon
#

How do I get the type of hand being played - I don't want the displayed hand name (because I want to make sure my joker still recognizes Royal Flush as a Straight Flush).

Namely, I want to find all the hand types available within the current hand, but then discard the one already recognized by the game

frosty dock
paper zealot
stable agate
#

do I keep the ability = extra = odds = 4?

paper zealot
#

Might as well, using named parameters makes things a little clearer imo

#

I know less about this side of things, but i think there are some circumstances in which context.other_card isn't defined, so maybe just do a nil check before accessing it

unkempt thicket
#

How can I manipulate a sprites rotation, position, scale, etc.? (and its layers)

paper zealot
#

Checking if invalid_case then return end might be better practice and easier to read, instead of nesting if statements

vague lantern
#

hey, what does bmm_storage.db do? the balatro mod manager says to delete it, but i don't want to delete any save data

paper zealot
#

It'll be regenerated if you click "Reindex mods" in BMM's settings menu, though be warned this will also delete any manually-installed mods

vague lantern
#

oke, dat's fine with me - just wanted to make sure no save data will be deleted

foggy carbon
#

how would I detect if the player is using OmegaNum for scoring? Would it be as simple as checking if chips or mult is a table instead of a number?

vague lantern
#

is there a way i can install the mod installer into my proton prefix for balatro? on linux

paper zealot
#

BMM doesn't currently work on Linux, no

normal crest
#

just taking a peek at talisman's src

vague lantern
west mason
#

how can i make 2 or more copies of the same joker have different random values at the same time, without one overriding the others?

vague lantern
#

or actually eh, maybe i should just take yer word for it lol

paper zealot
#

Oh, i missed the mention of Proton. It might work, though BMM depends on a few relatively new technologies that might not be present in or compatible with Linux + Proton

#

Worth a try though

vague lantern
#

hmm, i think i'll try it next time i delete all the modded stuff via a game update or file verification lol

rough furnace
#

this may mess up if the user changes the type of infinity but doesn't restart

foggy carbon
#

I think a lot of things break in that scenario

stable agate
# paper zealot A nil reference error on that line could be a number of things, try breaking it ...

I did my best to pick apart the pasta that was the line being a bunch of nested if statements and separate them. not getting a nil error on the suits now (thanks to just keeping everything the same from the modded castle2 joker), but we've hit a dreaded "arithmetic on field odds (nil value)"

    loc_vars = function(self, info_queue, card)
        return { vars = {

            (G.GAME.probabilities.normal or 1),
            card.ability.extra.odds
        } }
    end,
    calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if (context.other_card:is_suit(G.GAME.current_round.castle2_card.suit)) and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
if (pseudorandom('dizzy') < G.GAME.probabilities.normal/card.ability.extra.odds) then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
return {
extra = {focus = self, message = localize('k_plus_spectral'), func = function()
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.0,
func = (function()
local card = create_card('Spectral',G.consumeables, nil, nil, nil, nil, nil, 'dizzy')
card:add_to_deck()
G.consumeables:emplace(card)
G.GAME.consumeable_buffer = 0
return true
end)}))
end},
colour = G.C.SECONDARY_SET.Spectral,
card = card
}
end
end
end
end
}
local igo = Game.init_game_object
function Game:init_game_object()
    local ret = igo(self)
    ret.current_round.castle2_card = { suit = 'Spades' }
    return ret
end```

Got no clue if anything new can be gleamed from this layout. I appreciate your time and patience with me here, but this is stumping us
humble girder
#

indentation?

stable agate
#

formatting borked. I think I will die

#

We're gonna try this again tomorrow. Appreciate the help everyone

paper zealot
#

Feel free to ping whenever you come back

stable agate
spark remnant
#

I'm currently trying to create a joker that will trigger an effect for the first card of suit, what would the best way to do this be?

tall wharf
#

first card of suit?

spark remnant
#

*each suit

tall wharf
#

first card for each suit scored

spark remnant
#

yes

old bane
#

i think you could have a list like

suits = {
 [“Spades”] = false,
 [“Clubs”] = false,
etc.

and then set each to true as you find one of each suit

tall wharf
#

maybe you could use chad logic and check for unique suit

spark remnant
old bane
#

not individual

#

more like context.before or something

#

that way it gets reset when a new hand is plued

#

plyed

#

(im on phone if you cant tell lmao)

spark remnant
#

I tried using context.before but it just crashes when I play a hand

old bane
#

hm

#

i would show you how i do it but i dont have access to computer rn

#

_<

crystal perch
#

this is despite declaring 'odds' in both config and loc_vars

dusk harness
#

should this also work for vanilla jokers or only modded jokers?

ivory coral
# crystal perch

i presume the localization is displaying odds correctly, im not good with lua so this is a shot in the dark but the game seems to think card in line 521 is not, in fact, the card in question, since otherwise odds wouldnt be nil, maybe try using self instead? im not sure why that would fix it but its worth a shot

crystal perch
#

alright

ivory coral
#

and if it doesnt fix it maybe at least itll give you a new crash log that will be more useful

dusk harness
#

ok im going absolute bonkers, can someone plz help me out. i just want to get access to the loc_vars from any object, even vanilla ones, does anyone have ideas?

tall wharf
rough furnace
#

loc_vars is funny becasue its not actually a function for vanilla cards

#

just part of one

dusk harness
#

im hanging out in a vc in the cryptid discord can someone come explain to me whats actually going on?

#

like i have been banging my head violently for way too long and i need help

proven stump
dusk harness
crystal perch
#

i don't believe editions can trigger the same calculation methods as jokers

#

it looks like i might have to convert my idea into a joker sticker for full functionality

weak gate
#

trying to patch something over pokermon, but it doesn't seem to work - what may i be missing?

crystal perch
wet sentinel
#

Hello hi howdy! I tried looking online for modding guides, however i could only find ways to install mods, not make your own mods. I was planning on doing a joker/sprite reskin- how would I start doing that?

tall wharf
wet sentinel
#

Thank you! :3

runic pecan
#

I wonder if I can have functions in config.extra?

paper zealot
#

Functions are just ✨ fancy✨ variables

#

And dynamic typing means you can put anything anywhere. Whether it makes sense to is another matter

hearty crow
#

Hi there, is there any documentation on formatting text with smods?
cant find it on the github wiki (maybe im just blind :3)

runic pecan
hearty crow
#

yep

hearty crow
#

oh thanks, found it in the game files

runic pecan
hearty crow
#

sick sick

royal ridge
#

could we have a non-breaking target to prevent the 1 in 4 of glass from occurring? it's a popular modded effect but patching it seems unfeasible since no matter what you do, it's most likely breaking similar patches

#

something simple, just like

local willdestroy = true
-- TARGET: prevent glass break
if willdestroy then destroyed = true end
paper zealot
# hearty crow Hi there, is there any documentation on formatting text with smods? cant find it...

I might try and tackle this, it's often asked. Briefly:

  • Pre-defined colour: {C:<colour>}
  • Movement: {E:1} is floating text, {E:2} is bumping text
  • Hover tooltip: {T:<key>}, where <key> is an element in G.P_CENTERS or G.P_TAGS
  • Text background colour: {X:<colour>} (usually used as{X:mult,C:white})
  • Custom colour: {V:<number>}, where <number> is an index of a colour passed to the text localise() through args.colours
  • Text scale: {s:<number>}
  • Reset formatting: {}
#

(Replied to wrong comment)

runic pecan
#

Wait, I don't need to ,C:white after X:mult this whole time!?

rough furnace
#

they are combinable

#

adding both makes the text white the background mult

#

also each new set of brackets resets all previous ones

runic pecan
rough furnace
#

also for V: you can pass the colours to loc_ars

rough furnace
runic pecan
paper zealot
#

I'm in the mood to write documentation, I'll scribble up a proper list with examples and post it... somewhere. Mod Wiki probably

rough furnace
#

you can pr onto the smods wiki

paper zealot
#

It's all vanilla functionality so the Steamodded wiki might not be the most relevant place for it

rough furnace
#

we document a bunch of vanilla stuff

#

like the event system and ui system

paper zealot
#

I'd forgotten about the UI doc, that was super helpful for me. Alright, cool, will do

rough furnace
tall wharf
#

i am going to try to document my own mod on my wiki

minor furnace
#

Documentation? What's that?

tall wharf
#

chat what are we thinking

rough furnace
tall wharf
#

if scored cards sum is ≥ 15 x1.5 mult per scored cards and retrigger the card effect for a legendary

runic pecan
#

Is it 1 in 50 chance to hit the jackpot of $777,
or 1 in 50 chance to hit the jackpot with $777?
It was originally 1 in 50 chance to hit the jackpot and gain $777.

manic rune
#

this should uhh mean 5.1% right?

#

im bad at maths

rough furnace
jovial harness
#

How would I give a single joker a custom back sprite?

minor furnace
#

Somehow my 1x and 2x folders from my mod just... deleted their contents???

#

I had a backup and also saved it to my git but still

grim remnant
#

question; we're trying to make a blueprint-esque joker, and trying to add our

        local t = { vars = { VARIABLES_HERE } }
        if config.showOrigin then t.key = self.key..'_source' end
        return t
    end,```
thing to it, so we can properly add the description depending on the config setting. uh. how the HECK do we do that with this thing?
#

hmm. this doesn't crash, but it doesn't return t properly.

plush cove
#
poll_question_text

good idea

victor_answer_votes

6

total_votes

6

victor_answer_id

2

victor_answer_text

no

hearty crow
#

Can you animate a deck (as in the graphic of the preview card)
I've been trying to get the sprite sheet to work but when I tell the deck that I wanna use a sprite sheet as animation instead of just the first frame the game crashes

rose dragon
#

decks dont support animated textures

#

you'll have to use a static image and manually move the position in the objects center

manic rune
#

yeah uhhhhh

#

i dont understand pseudorandom_element ngl

#

😭

hearty crow
manic rune
#

if i want to randomly pick a character out of the pool, what would i need to do here?

vestal ore
#

wouldnt it just be pseudorandom_element(CharList[4])

manic rune
#

oh, i dont need the seed part?

#

yeah im dumb at this, thanks

vestal ore
#

if you want just slap in like pseudoseed('poop pant') as the second argument

#

for... random!

fathom thunder
#

why does it just proc again after the score is finalized??? did i do something wrong with contexts
for context here is the calculate function

calculate = function(self,card,context)
    if context.joker_main then
        if card.ability.extra.triggered == true then
            if pseudorandom("cerebella", 1, 500) == 1 then
                print("cat (it doesn't exist yet)")
            end
                -- and whatever else happens if its triggered it has to do with other jokers that arent implemented yet
        end
    end

    if context.individual and context.cardarea == G.hand then
        if context.other_card:is_suit('Diamonds') then
            card.ability.extra.triggered = true
            if context.other_card.debuff then
                return {
                    card = card,
                    message = localize('k_debuffed'),
                    colour = G.C.RED
                }
            else
                return {
                    card = card,
                    x_mult = card.ability.extra.xmult
                }
            end
        end
    end

    if context.after and context.cardarea == G.play or context.end_of_round then
            card.ability.extra.triggered = false
    end
end
runic pecan
fathom thunder
#

how do i differentiate between the two situations is there a third context

runic pecan
fathom thunder
#

ok that fixed it ty, didnt think to use contexts in a more logical way rather than just mindlessly throwing it in my code for the situation lmao

runic pecan
grim remnant
rose dragon
edgy reef
#

Lua basically treats return foo and bar or nil as if foo == <truthy value> then return bar else return nil (ish)

#

So t will never be the returned value (the table with main_end will instead) and the or nil will always be ignored.

grim remnant
#

tried a comma, that didn't work... what do?

#

since, literally everything works but the main_end for whatever reason. (for reference, there's supposed to be a "compatibile/incomaptible" after the origin tag from the lang.)

edgy reef
#

Add main_end into t and return just t

grim remnant
#

okay, well. that worked disturbingly effortlessly.

#

we're kinda scared how cuberry somehow has been the card that has been the easiest to implement thus far given his. uh. Meta-reptutation, in the source material. wouldn't surprise us if there's bugs we're yet to find, to be fair... ;P

edgy reef
#

(I don't have nitro I can't add the "read the docs" sticker)

grim remnant
#

ah, that would be the bug. he's supposed to trigger 3 times (one trigger and 2 retriggers, to be precise) for every time the joker activates, which doesn't work quite right for jokers that can, themselves, retrigger. (yes, we are acutely aware of how this could scale with some jokers and that's entirely the point given his rarity is this mod's equivalent to legendary ;P)

we assume our retrigger code is going to have to be a bit more sophisticated than it currently is, huh.

#

for reference, this is the current code (most of which is shamelessly pried from cryptid's old blueprint joker)

bold gyro
#

I'm trying to make a Joker that adds a randomised Stone card to the deck when chips > mult after scoring. The code below is mostly taken from the Marble Joker code in the lovely dump, and almost works, except that a floating copy of the Stone card stays on screen and does not go away. What below is causing that?

calculate = function(self, card, context)
        if context.cardarea == G.jokers and context.after then 
      if hand_chips > mult then
        G.E_MANAGER:add_event(Event({
          func = function() 
              local front = pseudorandom_element(G.P_CARDS, pseudoseed('earthquake' .. G.SEED))
              G.playing_card = (G.playing_card and G.playing_card + 1) or 1
              local card = Card(G.play.T.x + G.play.T.w/2, G.play.T.y, G.CARD_W, G.CARD_H, front, G.P_CENTERS.m_stone, {playing_card = G.playing_card})
              card:start_materialize({G.C.SECONDARY_SET.Enhanced})
              --G.play:emplace(card)
              table.insert(G.playing_cards, card)
              return true
          end}))

      G.E_MANAGER:add_event(Event({
          func = function() 
              G.deck.config.card_limit = G.deck.config.card_limit + 1
              return true
          end}))
          draw_card(G.play,G.deck, 90,'up', nil)  
        return {
              message = "Rumble!"
            }
      end
    end
    end
grim remnant
#

weird. even removing the retrigger section, he only seems to retrigger on the first 2 cards before just. stopping.

normal crest
#

which should probably be G.hand, since you don't want to emplace to G.play

#

But if marble joker has it that way then maybe it works and I'm just crazy

bold gyro
random sleet
#

G.deck

#

but also make sure you set the card's area since you are doing this the hard way instead of using SMODS.create_playing_card

#

oh the card gets drawn from G.play to G.deck

normal crest
#

SMODS doesn't have create_playing_card, it's just from vanilla iirc

random sleet
#

ok ill delete half my oddities then

bold gyro
#

Okay, the code works perfectly fine (the card does get added to the deck etc.) BUT there's a floating stone card that just kinda appears and is chilling around. It's a result of the Marble Joker making a Stone card appear in the middle of the screen at the start of round

random sleet
#

oh hm apparently i am using a base game function

bold gyro
#

me commenting out the --G.play:emplace(card) made it so I no longer got softlocked, but there's something else I need to get rid of (I think) that would prevent the floating card from appearing

random sleet
normal crest
#

The floating card is a result of not emplacing the card

bold gyro
#

Okay, it's fixed, thanks y'all! Here's what the fixed code looks like (I made some additional fixes):

calculate = function(self, card, context)
        if context.cardarea == G.jokers and context.after then 
      if hand_chips > mult then
        G.E_MANAGER:add_event(Event({
          func = function() 
              local front = pseudorandom_element(G.P_CARDS, pseudoseed('earthquake' .. G.SEED))
              G.playing_card = (G.playing_card and G.playing_card + 1) or 1
              local card = Card(G.play.T.x + G.play.T.w/2, G.play.T.y, G.CARD_W, G.CARD_H, front, G.P_CENTERS.m_stone, {playing_card = G.playing_card})
              card:start_materialize({G.C.SECONDARY_SET.Enhanced})
              G.deck:emplace(card)
              table.insert(G.playing_cards, card)
              return true
          end}))

        G.E_MANAGER:add_event(Event({
          func = function() 
              G.deck.config.card_limit = G.deck.config.card_limit + 1
              return true
          end}))
        return {
              message = "Rumble!"
            }
      end
    end
    end
grim remnant
normal crest
#

Could you send what your code looks like

#

The latest iteration of it

grim remnant
#

1 sec!

normal crest
# grim remnant

After calling calculate_joker you need to set blueprint and blueprint_card to nil

#

You will want to keep a reference to blueprint_card in a different variable to use afterwards

grim remnant
#

after line 166, right?

normal crest
#

correct

#

This is how vanilla blueprint does it

#

Except in your case self should be card

grim remnant
#

okay, that's... odd. it's still only retriggering twice if there's 2 jokers, and only retriggering additional times the more jokers there are. even tried to copy-paste the vanilla blueprint code, and it did the same thing?

#

which implies either an error in the for loop for other_joker, or somewhere in the update function

normal crest
#

What is your code now

grim remnant
normal crest
#

Additionally you might want to add and not context.no_blueprint like vanilla blueprint does

grim remnant
#

okay, there we go. now it works as we'd expect it to. the only thing would be adding the "it triggers 3 times" thing, but it's almost 3am, so that sounds a lot like tomorrow us' problem. ;P

neat plover
#

is discard.size an actual thing??

#

or is it not something i xan change

plain apex
neat plover
#

what

plain apex
#

y'know the ERROR of Spades

neat plover
#

oh yeah

#

the best playing card

plain apex
#

which despite being a "spade" is clearly a heart

#

great card that just crashes the game and also does not count for flush fives

neat plover
plain apex
#

don't think so

#

haven't heard of it anywhere atleast

#

💀

neat plover
#

WHAT DID YOU DO

#

oh no

#

its just a bleached card

plain apex
#

tried to create a random heart or spade card when blind is selected

#

so far i have done not that

neat plover
#

its a card at least

plain apex
#

chat whats worse an ERROR of spades that is a heart and crashes the game when played or a card with absolutely nothing on it that crashes the game when played

neat plover
#

error of spades is f u n n y

plain apex
#

true

#

is there a way to create a card that is specifically a suit?

#

because what im doing is absolutely not working lmao

shadow rapids
#

Random rank?

neat plover
#

yes i think

plain apex
#

yeah just like a random hearts card or spades card

#

got mimics in this before i got cards doing what they're supposed to do lol

#

y'all are NOT 2's of hearts

#

have a blank steel card lol

#

could be an interesting challenge run tho

#

your deck is getting filled with cards that crash the game if played

rough furnace
#

just put jokers in the area

plain apex
#

i mean wouldn't exactly be the same cause they stop being there and dont go back into the deck no?

foggy carbon
#

Do you guys agree this sounds like a legendary?

plush cove
#

if you level up high card a bunch, this could go insane

plain apex
#

true

frosty dock
#

indeed

rose dragon
plush cove
#

X2 mult for every unique Poker Hand included in what is played

frosty dock
#

there's 10 unique pairs in a 5oak

foggy carbon
#

I mean, I'd probably lower the rarity before changing the effect

foggy carbon
jovial harness
#

Nah, it'd be 5 choose 2 - which amounts to 10

foggy carbon
#

ahh

jovial harness
#

5x4 means that Card 5 - Card 1 is a different pair from Card 1 - Card 5

plush cove
#

evil deck idea: "Additive Deck"

chips and mult are added together rather than multiplied

foggy carbon
#

5oak would get 5oak + 4oak + 3oak + pair + high card

It's not 5 high + 10 pairs + 10 3oak + 5 4oak + 5oak

At least, that's not the impression I got from the way my brother suggested the joker

runic pecan
#

Still can't believe every hand can contain HC even when 4oak not containing 2p.

plush cove
#

flush five = flush five, flush, five of a kind, four of a kind, three of a kind, pair, high card

foggy carbon
#

which hand type gets the most sub-hands? Is it flush five?

crisp coral
#

its so fucking jank

main mica
#

the jimbo to wee pipeline

#

weeification

merry raven
#

Dear god it's so fucking peak

plush cove
crisp coral
#

the plan is. No

#

its gonna be debuffed when devoured

#

yum

plush cove
#

is this the vore you were referring to yesterday

crisp coral
#

maybe

merry raven
#

One of my Jokers has the function to change its suit for every round ended, but it's currently very vanilla, what changes can I make to support modded suits overall

crisp coral
#

SMODS.Suits

merry raven
#

Yeah I know it exists but how do I specifically use it

#

Do I replace all instance of suits with it

#

Oh wait

#

Found something I maybe could use

wintry solar
#

Yeah you can do that for suits too

neat plover
#

WHY DONT YOU WORK

random sleet
#

did you add mult_mod after that instance of the joker was created

neat plover
#

oh

#

right

#

i hate myself

random sleet
#

also does it actually exist also mult should be {C:mult} and not include the Mult text and there should be a space
effects that give money say "earn $#"
"X on start of blind" should be "When {C:attention}Blind{} is selected, X"

crisp coral
neat plover
#

what in the actual name of jimbo

wintry solar
#

Why do they spin 🤣

jovial harness
#

Why the dogy got helicopter mode!!!

crisp coral
#

had to go so.
what variable controls the height of the moveables?

#

oh sorry. depth

merry raven
#

I want to do particle effects on a Sticker, but does it support on_load, on_apply and on_remove like editions do?

#
on_apply = function(card)
        card.children.particles = Particles(1, 1, 0, 0, {
            timer = 0.03,
            scale = 0.3,
            speed = 1.2,
            behind = true,
            lifespan = 2,
            attach = card,
            colours = {G.C.PURPLE, lighten(G.C.PURPLE, 0.15), darken(G.C.PURPLE, 0.2)},
            fill = true
        })
    end,
    on_load = function(card)
        card.children.particles = Particles(1, 1, 0, 0, {
            timer = 0.03,
            scale = 0.3,
            speed = 1.2,
            behind = true,
            lifespan = 2,
            attach = card,
            colours = {G.C.PURPLE, lighten(G.C.PURPLE, 0.15), darken(G.C.PURPLE, 0.2)},
            fill = true
        })
    end,
    on_remove = function(card)
        card.children.particles:remove()
    end,

For instance this is how I do particles on Editions, but as far as I know, Stickers only has draw

neat plover
#

paranoid joker

#

wrong channel

#

how can i add more discard size?

jovial harness
neat plover
#

thanks

#

wait

#

i want to be able to discard more cards, not more discards

crisp coral
#

that's significantly harder to do

neat plover
#

whatever im ready... there is no turning back

jovial harness
#

Check Cryptid's source, I know they have vouchers + a joker that increases card selection size, that might be similar to what you want

burnt sonnet
#

If I want to debug hand calculation, is the best way of doing so just making a custom deck with the 5 starting cards I want, or is there a utility that lets me just customize the cards directly?

neat plover
#

what is the name of the voucher

plush cove
jovial harness
plush cove
#

fractal fingers is a Joker

neat plover
#

yeah i am not ready

#

scrapping that rn

crisp coral
#

iirc

#

Grabber is the +1 hand in vanilla

neat plover
#

thanks anyway

foggy carbon
#

how do I directly modify the chips and mult outside of a message proc

#

because this is displaying the message but not adding the chips or mult

manic rune
#

insane update speed

#

🗣️

frosty dock
#

you can just return the table you're defining as x here

#

or construct a return table if you need multiple messages

foggy carbon
#

oh?

#

like, push x into a table, then return the full table?

frosty dock
#

it basically supports you returning something like a linked list

#

the returned table can have an extra table which is evaluated as if it was also returned

#
local tail = {}
local head = tail
local function append_extra(t)
  head.extra = t
  head = head.extra
end
append_extra({ message = 'blah' })
-- etc.
return tail
random sleet
#

my recursive version is funnier and probably strictly worse

foggy carbon
#

okay, so now it updates the chips and mult correctly...but then after evaluating, it goes back to the default chips and mult for the hand

random sleet
#

quick question

#

what's v

foggy carbon
neat plover
#

fuck

#

wrong message

foggy carbon
#

line 61 will have the and false removed, just testing the loop itself detected proper hands

lucid sun
#

i tried to repurpose the abstract joker code to give $1 dollar per joker owned and idk what the hell happened, anyone able to tell me what i fucked up

jovial harness
#

You're not resetting dollar bonus

neat plover
#

yeah thats what i thought

jovial harness
#

Add a card.ability.extra.dollar_bonus = 0 before the loop

lucid sun
#

damn lol thank you

jovial harness
#

guhhhh this lovely patch doesn't seem to do anything to the joker with that specific name and when I set it to "true" it just throws up weird errors. i think i need to either give up on this silly easter egg or sleep on it for 500 years

manic rune
#

now how do i make a window pop out when i press the button

#

hmmm

frosty dock
foggy carbon
#

oh

frosty dock
#

I don't think we've added a context that allows base score to be modified in the way that blinds like the flint do

humble girder
#

that being said, hand_chips should already be populated in context.before shouldn't it?

#

and whatever the mult global is

#

it's a hack but works in theory /shrug

faint yacht
#

hand_chips and mult globals.

west mason
#

is there any way i can make these two values be random for each instance of the joker?

humble girder
#

randomize them in set_ability

west mason
#

inside or outside loc_vars?

#

i tried messing with set_ability yesterday but it gave me weird results like overwriting previous instances of the joker

humble girder
#

were you interacting with self

#

you shouldn't interact with self in a SMODS Center unless you know exactly what you're doing

west mason
#

yeah i was using self

humble girder
#

also loc_vars gets a card, not a center :v

manic rune
#

def watched the same tutorial as me

#

😭

west mason
humble girder
#
set_ability = function(self, card, initial, delay_sprites)
    local MIN_VALUE = 0
    local MAX_VALUE = 10
    local SEED = 'your_joker_id_here'
    card.ability.extra.RandomOddsJ = math.floor(MIN_VALUE + pseudorandom(SEED) * (MAX_VALUE + 1))
    card.ability.extra.RandomOddsT = math.floor(MIN_VALUE + pseudorandom(SEED) * (MAX_VALUE + 1))
end,
manic rune
#

wait r u the suits guy

humble girder
#

yes

spark remnant
#

I'm currently trying to create a joker that will trigger an effect for the first card each of suit scored, what would the best way to do this be? I understand I need to use some sort of list but not exactly sure how.

humble girder
#

this joker triggers on the first instance of each suit being scored

#

it can get a bit annoying with blueprint compatibility

#

if you want to do first card of each suit you'll also have to wrap your head around how you want to handle wild cards

foggy carbon
#

I was gonna mention how Flower Pot (the vanilla joker, not the stats-display mod) handles wild cards, but I realized that FP only works because it looks at the whole hand at once, whereas your idea instead looks at the hand in sequential order

humble girder
#

if you care about the first instance of each suit being scored you can get away with figuring it out as you go in scoring

#

if you care about the first card with each suit scored you do kinda do something like FP

wintry solar
humble girder
#

and figure out what's what in context.before

lucid sun
#

would anyone be able to look at this and help me, trying to make it so the joker gains chips when jack of spades is played but it does not increase? have tried both of these to no success

wintry solar
#

Context before doesn’t have an other_card

humble girder
#

where is your i coming from

foggy carbon
#

Flower Pot first looks for all non-wild cards, determines which suits are accounted for, and then uses wilds to fill in the blanks (one suit per wild).

I guess what you could do is, use context.before to sort out which cards get scored, and give them a flag, use context.individual to proc the joker's effect on any cards with the flag, and then use context.joker_main to remove all the flags (so that you don't have things from previous hands getting scored again.

lucid sun
spark remnant
humble girder
#

have to separately keep track of what each different card has already done in one scoring pass so that it works properly with blueprint/brainstorm

spark remnant
humble girder
#

I need to generalize it out to be able to handle any amounts of suits, but basically yes

#

if you think about it, a wild trigger is a wild trigger, it doesn't ever need to figure out what suit that actually was for the purpose of this joker

#

it will always trigger for a wild as long as it has triggered less than the total amount of suits in the game

spark remnant
#

ah ok, is that for if you have custom suits?

humble girder
#

well, yeah, if it wasn't hardcoded as 4 I'd just check the number of suits in SMODS.Suits

spark remnant
#

awesome, do you mind if I mostly copy your code?

inland shard
#

the following message is braptro approved

modern patio
#

Ong

spark remnant
#

my facade of lua knowledge has been damaged

crisp coral
#

why is there a braptro cult now

modern patio
#

Cause it being made by two incompetent individuals and someone who understands lua

spark remnant
#

*barely

modern patio
#

True

#

I mean i barely understand it

spark remnant
#

not even joking this is the first time i've properly used lua so I'm kinda learning as I go

modern patio
#

And part of the blala joker poker

tall wharf
modern patio
#

I mean if you are good at lua i we’ll send you a public copy tomorrow and ask you to make a simple joker possibly if @inland shard is fine with that

inland shard
#

wat

#

oh is this a job interview

#

hi welcome im the manager what do you bring to the team

primal robin
modern patio
#

Lmao

tall wharf
modern patio
merry raven
#

Braptro?
Tell me more

inland shard
#

eat pants

modern patio
primal robin
#

Me having 3+ mods in development: 💀

merry raven
#

Great Scott!!!!

modern patio
primal robin
#

I know

tall wharf
#

maxwell one was drawn by someone else

inland shard
#

fire

tall wharf
#

do you like it

inland shard
#

yeah

merry raven
#

Can i show my shit off

tall wharf
#

yes

inland shard
#

well yeah we all are already

merry raven
inland shard
#

holy

#

cool designs

tall wharf
modern patio
#

Might make that an expansion in the near future if you want

tall wharf
#

what expansion 😭

modern patio
#

Expansion are small samples of ideas

tall wharf
#

ah right

modern patio
#

The braptro has one call mythic

tall wharf
#

I'm sorry i just am not that competent at what i do lmao

modern patio
#

Which adds more rarity and challenges increasing the difficulty

modern patio
#

Im going to sleep to gn

tall wharf
#

gn

inland shard
#

this is sick tho

tall wharf
#

(i hate chemistry laboratory class)

hushed field
#

How often are destroy effects really a negative? I've been using them as a partial negative, but I'm considering whether I should refactor some destroy effects into permanent debuffs

#

Because cards that break are really just deck thinning, after all

inland shard
#

yeah being able to control card deletion is insanely powerful

#

debuffing is however fucking brutal since a majority of scoring jokers are based on rank and suit, so there would need to be an insane effect for the debuffing to be a good balance for the joker imo

tall wharf
#

X2 mult per card played 😭

hushed field
#

Hmm, yeah, control's a big part of it. Maybe I should leave the cards that randomly destroy a card to do just that.

#

I'll keep debuffing to a specific archetype. The fact that there are more methods of destroying cards does mean it's a bit less of a downside as well, after all

wintry solar
#

I think it's incredibly rare that destroying cards is a negative

tall wharf
#

is this too good LMAO

faint yacht
#

odd_todd Now pair it with this.

hushed field
#

I'll change my jump scare effect to a debuff 🤔 that should make it a bit more of an actual trade-off

tall wharf
#

it does not matter if you play

#

high card with 4 hands

#

ok i think this is just too good

inland shard
#

ULTRA BASED

normal glen
humble girder
spark remnant
#

Awesome, thanks

tall wharf
inland shard
#

coo

tall wharf
#

nvm where the FUCK do i

#

how do i destroy cards in the entire hand 😭

#

is G.play not it

shadow rapids
#

Should be destroy context

#

Return true

jade finch
#

Hi all! Im so sorry for the big post I don't mean to yap, i've just come across a werid problem.

I Was wondering if maybe I could get some insight when it comes to Balatro and Sound mods?

I was hoping to replace the BGM with some other choice selections. But what I came to find is that the audio for the mp3's wouldn't loop or be cut abruptly.

So far, from what I can tell the game has a max duration setting somewhere in the code? And all songs that the game uses are played at the same time, at the exact same length. So a song finishes (the shortest appearing to be 34 seconds) that is when the whole ost "loops"

Right now, I can only think of resolving this by cutting the ost into 34 seconds and making speed up and slow down variations of each. Im fine with that, but I was wondering if im just overlooking the setting that defines the cutoff for when a song might loop?

crisp coral
#

step 1: use oggs not mp3

#

there is no max duration for songs, they just loop when they finish

jade finch
#

So is my problem for the abrupt audio cuts just the filetype?

#

or rather the failed loops?

crisp coral
#

and the ingame music is 4 minutes long

crisp coral
tall wharf
#
    calculate = function(self, card, context)
        if context.joker_main then    
            return {
                xmult = card.ability.Xmult
            }
        end
        if context.individual and context.cardarea == G.play and #G.play.cards == math.floor(card.ability.card_target) then
            card.ability.Xmult = card.ability.Xmult + card.ability.extra
            return {
                message = 'Upgraded!',
                colour = G.C.MULT,
                card = card
            }
        end        
        if context.after and context.cardarea == G.play then
            if context.destroy_card.ability.aiko_about_to_be_destroyed then
                for i,k in ipairs(context.full_hand) do
                    k.ability.aiko_about_to_be_destroyed = true
                    k:start_dissolve({ G.C.BLACK }, nil, 4, false); 
                    k:juice_up(0.1) 
                end
            end

        end

        if context.destroy_card and context.cardarea == G.play and not context.blueprint and not context.destroy_card.ability.eternal then
            
            if context.destroy_card.ability.aiko_about_to_be_destroyed then
                return { remove = true }
            end
        end
    end,
#

i will cry

jade finch
crisp coral
#

god

jade finch
#

I guess, does anyone mod the balatro ost? I did search reddit but didn't see anyone mentioning touching that aspect. so I may just be in uncharted waters

crisp coral
#

there's a mod in the example mods folder

tall wharf
#

i am stupid wtf

crisp coral
tall wharf
#

i think osu also recommends ogg

#

not sure

crisp coral
#

ehhh ive seen high quality mp3s used

jade finch
crisp coral
#

ehhh no need

#

the example mod is what you want

stable agate
#

Forgive the early morning code yap, but I'm trying to have a joker do the following: if card held in hand is a number card, give +10 chips. if card held in hand is a number card and win a 1/3 chance, give 1 dollar

The chips part of this works, but not the dollars portion. Any help would be appreciated (I gotta try and split this up)

crisp coral
stable agate
#

huh it won't let me copy paste

crisp coral
stable agate
#
        if context.individual and context.cardarea == G.hand then
            if context.other_card:get_id() <= 10 then
                if context.other_card.debuff then 
                    return {
                        message = localize('k_debuffed'),
                                colour = G.C.RED,
                                card = card,
                    }
                else 
                    return {
                        chips = card.ability.extra.chips,
                        card = card
                    }
                end
            if (pseudorandom('decree') < G.GAME.probabilities.normal/card.ability.extra.odds) then
                if context.other_card.debuff then
                    return {
                        message = localize('k_debuffed'),
                        colour = G.C.RED,
                        card = card,
                    }
                else
                    G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + card.ability.extra.dollars
                            G.E_MANAGER:add_event(Event({func = (function() G.GAME.dollar_buffer = 0; return true end)}))
                            return {
                                dollars = card.ability.extra.dollars,
                                card = card
                            }
                end
            end
            end
    end
end
})```
#

okay that works let me format it

crisp coral
#

just return dollars don't need dollar buffer

stable agate
#

like this?

                if context.other_card.debuff then
                    return {
                        message = localize('k_debuffed'),
                        colour = G.C.RED,
                        card = card,
                    }
                else
                            return {
                                dollars = card.ability.extra.dollars,
                                card = card
                            }
                end
            end
            end
    end
end
})```
crisp coral
#

well what exactly doesn't work

#

the odds or the return

stable agate
#

care to give me one sec to isolate between the return and odds real quick?

crisp coral
#

huh?

stable agate
#

In my infinite wisdom, I actually had yet to check which part of the function wasn't working between those two

jade finch
#

Thank you so much!

stable agate
#

okay so it isn't returning the dollars value

tall wharf
#

should this not destroy the entire hand scored or not

humble girder
#

don't destroy cards like that

#

that's literally why context.destroy_card exists

tall wharf
humble girder
#

uhh what are you doing exactly

tall wharf
#

if played hand contains 4 cards destroy the entire hand

humble girder
#

why are you destroying those poor cards twice

#

gotta make sure they're extra dead?

tall wharf
#

yea

humble girder
#

i'm sure that won't cause weird shit to happen all the time

tall wharf
#

just wanted to make sure they are extra dead so they don't become ghost cards

atomic edge
#

if i want to check if a sold card is a negative joker what do i add to the

if context.selling_card then

#

or is there a mod that checks if a joker specificaly is sold that i can check out?

humble girder
#

if context.selling_card and context.card.ability.set == "Joker" and context.card.edition and context.card.edition.negative then

raw geyser
#

Is there a way to hide the Use button for a consumable?

crisp coral
#

hook to card:highlight

atomic edge
#

thanks so much

humble girder
#

don't start dissolving or juice

#

returning { remove = true } already will trigger the destruction of the card

tall wharf
#

alr

bold gyro
#

I'm trying to add a Negative playing card tooltip to a joker, but for some reason it isn't showing up when I use e_negative_playing_card. It works perfectly with any other edition. Is there a different key for the negative playing card?

loc_vars = function(self, info_queue, card)
    info_queue[#info_queue+1] = G.P_CENTERS.e_negative_playing_card
    return {
      vars = { card.ability.max_highlighted }
    }
  end```
tall wharf
atomic edge
atomic edge
#

shiet

humble girder
atomic edge
#

is dissolve the only function that destroys the cards or are there any else?

humble girder
#

i think all cards are destroyed by dissolving

#

not certain

atomic edge
#

oh great then thanks

tall wharf
#

i never had to do this before

humble girder
tall wharf
#

alr

#

makes sense yea

humble girder
#

heads up, i missed an s

tall wharf
#

thx

atomic edge
#

how can i get the name of the joker if its in a card

#

maybe i phrased it wrong

#

so like for example

#

or its id

#

its whatever just important its unique

tepid crow
#

you usually use .config.center.key for that

atomic edge
#

oh thanks

bold gyro
#

also, how how do you add seal tooltips to Jokers? Like editions have G.P_CENTERS.e_edition and enhancements have G.P_CENTERS.m_enhancement

strong jacinth
#

Yoo

#

I have like 95 questions.

  1. How do I use the config with UI
  2. How do I create/modify UI
  3. How do I create something similar to the Nope text from the wheel of fortune
  4. How do i check what cards the player has in the full deck
copper ermine
#

one of my concept jokers makes scaling jokers scale twice as quickly (so for example green joker would gain +2 mult per hand, wee joker would gain 16, etc) is this possible + how would i implement this like do i have to specify and modify every vanilla scaling joker

strong jacinth
copper ermine
#

lol

strong jacinth
#

But i cant say anything. My jokers are broken(er?)

manic rune
#

yeah so uh currently

#

it still acknowledges that a card is in the new card area

#

but it doesnt seem to render anything

#

odd

random sleet
strong jacinth
manic rune
#

nope, its an entirely new card area

hushed field
# random sleet

the six elements, earth, fire, stars, more earth, mario and glass

strong jacinth
#

(Curius)

manic rune
#

its where the joker card area is

#

when you press the Show Gacha Results button, an UI comes down which takes its position

#

totally not inspired by joyousspring whatsoever

manic rune
#

i have this thing

hardy viper
manic rune
#

which uhhhh gachas ❤️

#

but basically currently, it only gives you a joker of the highest rarity rn

tall wharf
manic rune
#

💀

strong jacinth
manic rune
#

it will add all the 5 jokers you rolled from the ticket there

#

then you can choose to add them to your joker area or not

#

the next time you use the ticket, everything in the gacha results area is wiped

#

that is if i can even see the card in the card area

#

odd

manic rune
#

i dont know how but your mod always seems to have every ui element i need

#

🙏

west mason
#

here's the PSA Slab Joker fully finished with the random card grading values for each copy of the joker

manic rune
west mason
#

its a random rare joker after all

autumn coral
#

you should make a shader that adds a random smudge in some part of it that is barely noticeable like 1x2 pixels and then make it a psa 6 because of it

stable agate
#

if I'm wanting to check that a card has NO enhancement, is checking something like other_card.ability == false possible, or do I have to manually input other_card.ability.name ~= "enhancement name"?

hushed field
hardy viper
hushed field
# stable agate Thanks

though you may want to use SMODS.has_enhancement, which I think can also check for base

#

Depending on whether you wanna check for whether the card is enhanced, or is going to count for an enhancement

stable agate
#

Just check if it's enhanced. The desired effect is unenhanced 2-5's gain extra chips

hushed field
#

SMODS supports quantum enhancements which is for jokers that have effects like (all 7s count as Lucky cards). Just checking G.P_CENTERS.c_base will not count those enhancements. has_enhancement will. Though if you're not using quantum enhancements, it's really only something to think about when it comes to mod compatibility

onyx sonnet
stable agate
#

I'm wanting to think about it now just in case, because several mods add unique enhancements. But stuff like "all x cards count as y enhancement" isn't what I'm looking to debuff necessarily. I'd only want to do something like if you had paradolia to turn cards gold through midas mask, detect that they are in fact golden and don't trigger the joker

strong jacinth
#

Does anyone maybe know

broken cliff
#

might help u

#

u can also check previews

hushed field
onyx sonnet
#

Ah, ic

#

Good luck in doing so!

manic rune
#

yeah uh real quick, is this the correct check for 0.6% rng stuff?

#

randomRNG is pseudorandom

broken cliff
manic rune
#

its 6

#

theres /1000 at the end to effectively cut it down to 0.6%

#

(at least, thats what i think it should do)

broken cliff
#

isnt randomrng a value from 0 to 1

#

actually yh

#

its right

#

should be

manic rune
#

im honestly hitting that 0.6% a lot, not sure if im messing up something or its genuinely just my luck 😭

#

i printed all the numbers to make sure, it is indeed 0.006 after the /1000

broken cliff
#

theres 2 conditions

manic rune
#

you would need SpecialPity to hit 90

#

aka uhhh

grim remnant
#

it seems tomorrow enough. how can we make it so a blueprint procs its effect three times instead of just once? tried to have 3 calls of other_joker_ret on line 169, which. did not work. ;P

manic rune
#

about 18 uses of the item

#

so its definitely not the problem, i also printed SpecialPity whenever i used the item too lol

broken cliff
#

or updates

manic rune
broken cliff
#

hm

manic rune
#

but maybe it is my luck, thats the hard part about debugging rng stuff

tall wharf
#

ok it's barely related

manic rune
#

you never know if its bugged or not

#

😭

tall wharf
#

i just realized what psa slab is

broken cliff
#

thats how it works in almanac ig

#

it divides 1 by a probability

#

1/36, 1/50, 1/1000

#

and it also does < instead of <=

tepid crow