#💻・modding-dev

1 messages · Page 110 of 1

wintry solar
#

The lines in between?

zealous glen
wintry solar
#

I did yeah

zealous glen
wintry solar
#

It’s something to do with how the engine scales images, I believe it’s internal to love2d

zealous glen
#

@wintry solar You had recommended that I make a border at the shader level. Do you know how I could do that?

frosty dock
#

looking at sticker calc rn, why are end of round effects this annoying

wintry solar
zealous glen
#

But how do I know what pixels are the outer pixels

#

Especially if I wanted that rounded card look

#

I mean, I could make a helper atlas that serves as a mask, but maybe there's a pure shader-level solution

wintry solar
#

Something like uv.x < 0.1 || uv.x > 0.9

#

And similarly for y

#

Then you can math out the corners too

stiff locust
#

how do i info queue a seal

#

g.p_centers and then what

#

s.sealname?

frosty dock
#

{ set = 'Other', key = 'key_here' }

stiff locust
#

oh

#

okay

#

alright is there a way i can suppress or alter the message given when adding chips

zealous glen
languid mirage
zealous glen
#

I need to make it not an edition

#

Also

#

I used your Tilted as a reference

#

Do I need to keep your accreditation?

languid mirage
zealous glen
#

But it doesn’t explain what it does

languid mirage
#

Problem is with how shaders work

#

in vanilla game you draw a shader off of a texture sprite, while your enhancement shader would not create a texture, it would draw directly to canvas, and edition will only get the plain texture of the sprite, unless you change how it works

#

theres a few ways, you could draw on to a sprite but iirc creating a sprite every frame is pretty resource intensive

#

and the other way would require changing how card:draw works completely

languid mirage
zealous glen
#

I think everything else is, like, vanilla shader code

#

That was also inside Tilted

frosty dock
languid mirage
tepid sky
wintry solar
wintry solar
frosty dock
#

made a draft PR for what I have so far on top of the enhancement calc PR but it's pretty bad rn

#

I've managed to make a sticker trigger on joker contexts like skipping_booster that don't normally use eval_card though

#

feels like i'm just making things more scuffed rather than less tbh

wintry solar
#

I’ll take a look shortly, I was planning on adding the consistent keys to return in that PR too

storm oar
#

would it be safe to hook the card sprite drawing function to add some extra stuff?

wintry solar
#

This is turning into better calc 2.0 🙃

frosty dock
#

if we go down that route, there might just not be a way around redoing evaluate_play in full

zealous glen
#

At the very least I'd need to know the size of a pixel in floats

frosty dock
#

ideally with some util function that consistently does returned effects

zealous glen
#

As in the side length

zealous glen
zealous glen
#

betterer calc

frosty dock
zealous glen
wintry solar
#

So you can just trial and error to find the correct number

zealous glen
#

Yes, but if I don't get the size right I'd end up with mixels

wintry solar
#

I actually don’t think evaluate play needs too much rewriting unless we want to add Utils for adding extra stuff into it without needing to lovely patch

zealous glen
#

please add those utils

storm oar
#

that way it's able to be told apart visually from regular cards

wintry solar
storm oar
#

and i could end up throwing any other effects into the same thing which would make things way easier

frosty dock
#

I'd want these utils, at least for the sake of stickers (I've tried to kind of include that in eval_card, but it's way too inconsistent in how it handles returned effects)

zealous glen
#

@frosty dock Funny you say that because I'm asking Eremel how to add a border around a card using shaders

#

Depending on the kind of effect you want you don't need to hook or patch

storm oar
#

is it possible to add another texture input for a shader? if so you could just easily do a mask texture

zealous glen
#

It should be, I was just wondering if there was a pure shader-level solution

storm oar
#

just white for the card shape, black around the outside, and multiply the output of the shader by that

storm oar
#

shader-level border would result in needing more calculations which would make it not as efficient, not noticeably any slower unless there's a ton of cards with the same shader

#

a mask would be the simpler solution too

frosty dock
wintry solar
#

Yeah I want to write joker calc like I’ve done enhancement and seals

zealous glen
wintry solar
#

They just don’t have consistent keys in returns iirc

#

God overwriting evaluate play would break so many mods 🙃

zealous glen
frosty dock
#

should be fine if it takes all keys in effects maybe, not sure what other inconsistencies there are

night pagoda
#

Noticed that upon stopping hovering on any description containing cards (like poker hand examples in the run menu), it causes a lot of weird events to appear in the queue (checked with DebugPlus only)

Upon hovering a lot and quickly switching to the game the events happening in the queue hinder the other events (such as playing cards), but it's really hard to get the timing right. The more cards the description contained, the more events appear in the info queue

Suspecting maybe start_dissolve starts happening for each card after the description disappears?

zealous glen
frosty dock
#

changes name to God

zealous glen
#

God flooding the world would break so many houses

storm oar
#

i'm adding a new thing to the cards since i don't want to replace enhancements or editions, the idea is that each card has a chance to be carried over to a new run if you have the voucher for it and i don't want to replace anything about the cards in that case

zealous glen
storm oar
#

i guess the card_ui patch would be where i should look at?

wintry solar
#

Is it just a different sprite you want to draw?

storm oar
#

yeah i'm wanting to add an animated border to the cards that have been brought over from the previous run

wintry solar
#

uhhh animated would be harder

#

I havent really looked at how the animated sprites actually work

zealous glen
storm oar
#

i would think it wouldn't be toooo complicated to do an animated effect

zealous glen
#

Use the atlas’ name to find out what objects use those elements

#

Then see what changes the draw pipeline to draw them over

storm oar
#

and yeah it looks like there's a patch for card.lua that is in the draw function so probably simple to do that

zealous glen
#

Math recreated animated sprites for Aura

#

Well, it’s a hacky change of normal inanimate sprites

#

But it works

storm oar
#

ah. well, for now while i'm just trying to get things working functionally i could just skip that part

#

just have a basic overlay sprite

zealous glen
#

That’s what I did for Temporary cards

frosty dock
zealous glen
#

Nor how to fix it

frosty dock
#

there's this but I'm not sure how relevant it is to anything

zealous glen
#

I think when I looked at it I suspected it was because AnimatedSprite didn’t have all the methods of Sprite

frosty dock
#

that's not possible, it derives from Sprite

zealous glen
#

Then I think I did not suspect that

#

Maybe it overwrote some specific method

frosty dock
#

at the very least my fake blind collection cards work well enough with animated sprites

zealous glen
#

So maybe it breaks during normal gameplay

#

But not where your fake Blinds are

frosty dock
#

iunno

wintry solar
#

I suppose I should work off the sticker calc pr now

storm oar
#

would there be some weirdness with if i were to make the sprite for the modifier be larger than the card sprite to add more than a 1px border?

zealous glen
#

I haven’t come back to this yet, but here are some oversized Enhancements @storm oar

#

Since you want to draw it on top, that might be less problematic

storm oar
#

also are there any issues with alpha with sprites at all?

frosty dock
storm oar
#

or would some partial transparency on sprites be fine?

zealous glen
#

Glass

storm oar
#

ah...right forgot that existed

#

i haven't played the game a ton, only about 12 hrs total so far

wintry solar
frosty dock
#

for stickers to be calculated using eval_play effect tables in joker and playing card contexts, extended returns in joker eval, probably some kind of util to evaluate effects consistently if we can help it

#

also no calling calculate_joker directly though I think I already took care of most of that, we want either eval_card or some wrapper to it that includes effects-related things

wintry solar
#

I wish I understood how retrigger api works

teal estuary
#

i have a question about the enhancement calc fixing, would it be possible to make in-hand retriggers? i presume it'd be something like:

if context.cardarea == G.hand and context.repetition_only then
[code that makes played card retriggers, too early to write it all out]
return{
repetitions = card.ability.extra.repetitions
message = "Again!"

its a random idea i had, but was just curious if it was possible

#

so, e.g, an enhancement could retrigger all cards played when held in hand

frosty dock
night pagoda
#

Is there a way to check which events are currently in the event queue?

wicked leaf
#

Help Needed: Destroying a specific type of joker when card is picked up

wintry solar
#

joker_retrigger.toml
Ctrl+A
Ctrl+/

frosty dock
#

joker_retrigger.toml
Ctrl+A
Backspace

wintry solar
#

ah but I might need to reference it when reimplementing it

#

it's supposed to retrigger other jokers right?

crisp coral
rough furnace
#

Iirc you can do G.E_MANAGER.queue.base for the main qieue. You can see the event with G.E_MANAGER.queue.base[1] and if you need info about the function try debug.getinfo(G.E_MANAGER.queue.base[1].func)

wintry solar
#

don't you love trying to work out why your code isn't working and then realising you've just editted the lovely dump

frosty dock
#

i can't say that hasn't happened to me

#

i love writing abstract code and forgetting about config I need to add

zealous glen
teal estuary
#

-# can red seals retrigger in-hand? thats a thing?

zealous glen
#

Always has been

storm oar
#

okay so it seems a negative x/y position for a sprite doesnt work?

#

so how do i offset the sprite for my overlay for cards so it properly displays?

zealous glen
#

Good question

#

I’d also like to know

crisp coral
#

what kind of overlay?

storm oar
#

just an added sprite

#

for now at least, i plan to make it an animated sprite later, just using a regular one for testing

crisp coral
#

is it properly 71x95?

storm oar
#

no, it's slightly larger so i can make a border that's more than 1 px around the card

crisp coral
#

hm

frosty dock
#

alright my reusable collection code covers jokers, all consumables and booster packs... time to work out how to include card modifiers

teal estuary
frosty dock
#

tags and blinds are too unique and who cares about the deck collection

#

vouchers exist

crisp coral
#

i don't know the exact values (balatro's system is a fuck (use debugplus eval)) but you can do some math to calculate the overlay's values compared to the card's

storm oar
#

ah any x and y values seem to be ignored for cards i guess

#

unless, is it not pixels?

crisp coral
#

x and y offsets the sprites i think??? but something about bonds that make them Not Work

#

also they are very much Not Pixels lol

storm oar
#

oh i thought it would be like a pixel offset

#

what unit is it then?

crisp coral
#

balatro unit

#

hell if i know

storm oar
#

i guess what i could do is like set it to some variable i can manipulate using debugplus to test?

fading fox
#

is there any way to force give jokers for testing?

storm oar
#

collection, hover over it, press 3

#

i think debugplus adds that?

fading fox
frosty dock
fading fox
crisp coral
#

BALATRO MATH LFGGGGGGGGGGGGG

frosty dock
fading fox
#

thanks ik it was something dumb I was forgeting

frosty dock
#

it doesn't work if you put it on a pre-existing card that was already undiscovered though, due to it being saved as such in your profile

storm oar
#

so should i just do -G.CARD_W*0.0704 for an equivalent of 5px offset?

#

and same for height but whatever 5/95 is

crisp coral
#

buh

rough furnace
#

Cnst you just specify how big the cards are in your atlas definiition?

storm oar
#

but it doesnt center the sprite, it's pinned to the top left of the cards

rough furnace
#

Yes

#

But since your cards are the exact size it will always be a full card

storm oar
#

the issue is the sprite is larger than a card and i want to offset it so that it is a border around the card

rough furnace
#

So this is something like a seal where it's on top of a card?

storm oar
#

yeah

rough furnace
#

Oh hmm that is a bit tricker then

fading fox
#

does anyone know what attempt to index global 'context' [a nil value] means?

#

just built my first full modded joker and as soon as I click a card in my hand while having it my game crashes and I get that as an error message

rough furnace
#

It means you tried to access a value off of something called context but context is nil

fading fox
#

nevermind I was missing another fucking comma

zealous glen
#

the alignment I think is center middle

#

but center center would make it look like it's a border around the card

storm oar
#

screw it, i'll just make it just draw into the card instead

#

cause it seems like everything i try isn't working

zealous glen
#

might not look good though

#

you can scale that layer up

storm oar
#

okay finally figured it out mostly

#

now i just need to figure out the positioning properly

#

but i can actually move it now

wintry solar
frosty dock
#

-# actually i forgot to remove a commented-out function, this should be even more

#

yes i standardized collection UI (except blinds, tags and decks)

storm oar
#

is there a way for vouchers in collection to not be grouped by 2s for certain vouchers? cause i'm not sure if i'm going to make upgraded versions of the afterlife vouchers or not

frosty dock
#

it uses a special type of card area that always has these groupings

#

you could dig as deep as to change how it works depending on the cards, but i don't think it's worthwhile

wintry solar
#

I might have this done later this evening

#

how exciting

frosty dock
#

nice

storm oar
#

ah fun

frosty dock
#

-# meanwhile i spent like 2 hours on something that makes no visual difference

storm oar
#

so, in the deck view the thing is offset slightly

#

but in the hand it's fine

storm oar
#

vs in the deck view

muted timber
#

oh this is how u do it

#

finally it works

frosty dock
#

also i just realized i left some test code in the rental calc function 🤪

storm oar
#

sprite is a wip, i'm planning to make it look fancier later

#

like a kinda spectral fire looking thing idk

#

while it's just sitting there it's fine, while dragging it it seems to offset it slightly

#

yeah i noticed

#

at least i have somewhat of an idea of how to mess with that now though

#

does copy_card work for jokers as well?

zealous glen
storm oar
#

the positioning itself or fully adding a new sprite to the cards?

zealous glen
storm oar
#

in the draw_shader calls, i added nil, nil, -G.CARD_W*G.RCOXV,-G.CARD_H*G.RCOYV to after self.children.center in the arguments, i added RCOXV and RCOYV as values i can change to test positioning, the 2 nils are because the arguments after are scale, rotation, x, y

#

maybe i should do self.T.w and self.T.h instead and that would fix the weird offset issue?

wooden nexus
storm oar
#

new suits?

wooden nexus
#

Porting over from my game

teal estuary
wooden nexus
#

What tree?

teal estuary
#

the bottom one kinda looks like a tree to me

#

it reminds me of the album cover for 7-3 in ultrakill

wooden nexus
#

They’re Paddles

teal estuary
#

makes sense

night pagoda
teal estuary
#

i like it though

wooden nexus
storm oar
#

it's a patch for the drawing function to add the sprite to the card but here's the full thing

[manifest]
version = "1.0.0"
dump_lua = true
priority = 1

[[patches]]
[patches.pattern]
target = "card.lua"
pattern = "elseif self.sprite_facing == 'back' then"
position = "before"
payload = '''
for _, v in ipairs(G.afterlife_modifiers) do
    if self.ability[v] then
        G.afterlife_modifier_sprites[v].role.draw_major = self
        G.afterlife_modifier_sprites[v]:draw_shader('dissolve', nil, nil, nil, self.children.center,nil,nil, -self.T.w*G.RCOXV,-self.T.h*G.RCOYV)
        G.afterlife_modifier_sprites[v]:draw_shader('voucher', nil, self.ARGS.send_to_shader, nil, self.children.center, nil, nil, -self.T.w*G.RCOXV,-self.T.h*G.RCOYV)
    end
end'''
match_indent = true

[[patches]]
[patches.pattern]
target = "game.lua"
pattern = "set_profile_progress()"
position = "before"
payload = '''
self.afterlife_modifiers = {
    "reincarnated"
}

local modifiers_atlas = self.ASSET_ATLAS["ns_aftrlfe_AfterlifeModifiers"]
self.afterlife_modifier_sprites = {
    reincarnated = Sprite(0,0, self.CARD_W*1.1408, self.CARD_H*1.1052, modifiers_atlas, {x = 0, y = 0})
}
'''
match_indent = true
wooden nexus
#

To show it was from my game i posted the wip sprite

#

Just balatrofied

drowsy tulip
#

can anybody help? trying to make a new consumabletype and the name doesnt seem to show up

storm oar
#

also yeah it seems using self.T.w and self.T.h instead of G.CARD_W and G.CARD_H fixed the issue with it being offset

#

at least the differences in the deck and hand

#

but it still offsets slightly when dragging the card but that's not tooooo bad, i can just make it go slightly further into the card to hide that

#

i think that has something to do with the parallax

night saddle
#

How do I read the card being discarded to see if they are faces?

proper relic
#

I think there’s a card:is_face() a function?

storm oar
#

just as a test i made it guaranteed for jokers to carry over too

#

should i make the chance vary based on rarity of the jokers?

#

also is there a way I could make it so that during the transition to the new run screen, it shows the voucher, dissolves it away, and a joker materializes?

#

also hm. there's a weird issue where sometimes the game decides to not properly start the new run, instead just goes to black screen

#

well, made some good progress before work today

vapid mango
#

fun question

#

And I've made changes to the joker cards, as well as the diamond collabs and the SHOP sign in game

#

When setting up the lua, how would I go about assigning the textures to the collabs and shop sign itself?

storm oar
#

not sure about the shop sign, but you can look at the NegateTexturePack mod in Steamodded example mods

#

probably the same thing but just needing to figure out the atlas name or something

vapid mango
#

gotcha

frosty dock
#

why would you replace the collab when you can just add them

storm oar
#

should i make a thread for my mod yet even though it's still a wip or wait till i get to where i can release it?

frosty dock
#

feel free to make a thread

rough furnace
#

someone save me

storm oar
#

oh no

#

ui is something i hope to never have to mess with more than i already have

gaunt thistle
vapid mango
#

well, one suits collabs

storm oar
#

yeah but you can add it

#

steamodded has SMODS.DeckSkin

#

i think i might make some myself, maybe based off some bands i like

vapid mango
#

hmm

#

Can anyone potentially tell why this would crash my game on launch?

frosty dock
#

probably

#

it'd help to see the crash message though

autumn coral
#

steammodded won't throw a fit if i have another json file in my mod directory... right...?

#

like an unrelated json file

#

honestly it doesn't really matter now that i'm thinking about it i could just give it a different extension lol

frosty dock
#

it'll just ignore json files that dont look like mod metadata

autumn coral
#

oh

#

alr

frosty dock
#

it'll log that it ignored it, but that's all

vapid mango
#

function SMODS.INIT.Colors()

#

That's what i was missing, ugh

frosty dock
#

uhhh

#

why are you making a mod for old steamodded?

#

could have seen that right away if Discord's mobile UI wasn't stupid

vapid mango
#

It's the one I'm understanding atm, mainly

frosty dock
#

there's no reason to do that

#

it doesn't even have good docs

#

and uh

#

it's 8 months unmaintained

vapid mango
#

oop

#

what would be a better option?

frosty dock
dense geyser
#

Listening into this conversation.. just starting on something today myself. Steamodded sent me to its wiki..

#

phew, I'm safe. Hah.

vapid mango
dense geyser
#

Just gotta figure out how to add a button to the Collection screen and put together a little baby-UI.

frosty dock
#

I'm not stopping you, the old format is still technically supported by the loader but no one will help you with it

vapid mango
#

or wait

#

the alpha, gotcha

#

god, wait, im dumb

#

writing in the old format but it's still supported by the new format

#

gotcha

frosty dock
frosty dock
vapid mango
#

gotcha kekw

#

my fault og

frosty dock
#

it's a genuinely bad system, that's why we changed it

teal estuary
#

i remeber looking at it when the docs still showed the 0.9.8, and nope

#

i felt my life being shortened

vapid mango
#

I mean, it's fairly easy to understand, but that's coming from someone who hasn't coded lua since roblox before tix left

frosty dock
teal estuary
#

the only modding i’ve done is factorio, it is in lua but not the same

rough furnace
#

I had a cursed idea last night while truing to sleep seeing if I can implement it

teal estuary
vapid mango
#

Well, it's gonna be fun to try and figure out the new system and implement these

teal estuary
#

rven just writing documentation

teal estuary
# vapid mango

i literally woke up today and thought “hrm. dark mode jimbo”

vapid mango
#

I am entirely unaware of how to go about this in this method but, as a great philosopher once said

#

fuck it, we ball

dense geyser
#

Hah. I'm looking to put together an basic in-game stats tracker. I find it kinda incredible that we don't have any semblence of run history available to us.

gaunt thistle
#

it is surprising, yeah

#

carpe diem

dense geyser
#

Whomever put together Steamodded should be commended. That thing really makes this much more straight forward.

frosty dock
#

I don't like to claim credit for it, it's very much a community-run project
-# but I'm the top contributor, just saying

#

so thanks I guess

rough furnace
#

Does anyone know off the top of their head any jokers that have text that does the kind of type effect in it's description

#

I know they exist but I don't rmeenber which ones have it

frosty dock
#

I'm not sure any vanilla jokers do

dense geyser
#

Good to know. I'll keep that in mind as I go about my business, that it may be worth cleaning stuff up to make it generic enough to be useful to the community.

rough furnace
#

oh oops does it

frosty dock
#

the soul

rough furnace
#

on the string probabilities

hardy viper
#

nodes[1].nodes[1].nodes[1] users hate this one simple trick

#

oh forgot the return

#

i should make this actually useful hang on

#

hm

#

wonder how id do that

gaunt thistle
#

smods devs are top-tier

tepid crow
hardy viper
# hardy viper

i imagine the only way to use this as it is would be to find a value in a config and then assign that config an ID and then use uie by id

frosty dock
gaunt thistle
#

lies, no one maintains lovely

hardy viper
#

but meh modifying an argument helps with preventing memleaks

gaunt thistle
#

it just exists

tepid crow
gaunt thistle
teal estuary
#

question, how would one request something to be added to smods? specifically example stuff

gaunt thistle
#

just in general better imho

dense geyser
#

Looked at Divvy's History. It describes itself as only saving hands and allowing for replay. I'll look at Flowerpot.

hardy viper
frosty dock
gaunt thistle
hardy viper
#

darn

gaunt thistle
#

I meant to expand on what you said

#

but yeah, we did basically say the same thing

gaunt thistle
rough furnace
vapid mango
teal estuary
#

its much more optimised balatrojoker

gaunt thistle
#

BASIC would probably be better

gaunt thistle
teal estuary
#

😭

#

be more understandable

gaunt thistle
#

speaking of toml ```lua
-- [lovely.pattern_patch]
-- target = "game.lua"
-- pattern = "new_cards[#new_cards+1] = _card"
-- position = "before"
function Cryptid_the_cryptid(check_for_unlock, _card)
if _card.config.center.key == "c_cryptid" then check_for_unlock({type = "cryptid_the_cryptid"}) end
end

#

plans for manifest v2

rough furnace
#

oh intresting

#

is it running code or is just like so we can

#

use lua formatting

gaunt thistle
#

the latter

rough furnace
#

sorry my sister hit the enter key on my keybaord

gaunt thistle
#

is that your OC or are you being serious

rough furnace
#

I'm being serious that is why that message is weirdly split

gaunt thistle
#

gotcha

#

my brain connected those two so I didn't even notice

gaunt thistle
vapid mango
#

Ok, so heres a fun question

gaunt thistle
#

at least for writing code

rough furnace
#

toml at least has multiline strings

vapid mango
#

How would i find out the key for the shop texture itself?

gaunt thistle
#

multiline patterns work fine

#

but fair

frosty dock
#

but how

rough furnace
#

yeah there was multiline paterns added but we had collective amnesia and forgor

gaunt thistle
#

using magic I didn't consider when I quickly assumed you were asking generically about multiline patterns

dense geyser
#

@tepid crow Thanks for pointing it out. Flowerpot is close to what I'm looking for.. but not quite. I'll bet I could build on what they've done to accomplish what I'd like to see.

vapid mango
#

Cause I've looked through the github and cannot for the life of me seem to figure this out

gaunt thistle
#

defining multiline patterns as a lua comment is more funky

#

the easy way is to force everyone to become civilized and use regec

frosty dock
#

crazy idea

hardy viper
gaunt thistle
#

I wish lua's syntax had function decorators

frosty dock
#
--[[ pattern = "multiline
pattern"]]
#

tbh that looks bad

rough furnace
#

metatables

gaunt thistle
#

thanks discord

vapid mango
#

Aure, I apologize for interrupting, but would you happen to have any idea about this issue?

frosty dock
#

thanks spaghetti monster

rough furnace
#

thanks

frosty dock
gaunt thistle
rough furnace
#

anyone got an example of a mod with a weird/complex hover thing

vapid mango
#

Or is it on the steamodded wiki and im blind

frosty dock
vapid mango
#

oh that was fast

frosty dock
#

-# it's not that hidden, it's just not in the main sidebar

gaunt thistle
#

:sus:

vapid mango
#

I had originally planned to just try shop_sign but i sat there for a minute like...

gaunt thistle
vapid mango
#

"Nah... Nah, it wouldn't be that simple"

frosty dock
#

lol

gaunt thistle
#

it's not entirely related obviously but the backing implementation might be useful

frosty dock
gaunt thistle
#

hi jack smods

#

well I guess everyone's been fine so far without it

rough furnace
#

(I alreayd do my own ui in DebugPlus)

gaunt thistle
#

valid

rough furnace
#
  • as a costurctur goes hard
gaunt thistle
#

also I can't scroll up the log in dp :-(

vapid mango
#

Just kinda guessed the dimensions and got real close lmao

frosty dock
#

we love you ve operator overriding

hardy viper
rough furnace
frosty dock
gaunt thistle
#

go_to_twitter sounds like an insult

hardy viper
frosty dock
#

it's annoying when printing large tables

gaunt thistle
#

please

vapid mango
rough furnace
#

also maybe you have a large number of logs that are hidden (I broke scrolling kinda)

rough furnace
#

however I don't have proper ways to handle text rn

#

Maybe I'll see about forcing monospace text

gaunt thistle
#

vim is a lot of fun to learn. I find that I rarely use and advanced features of it, I just like the text navigation part

rough furnace
#

can someone give me a crash course on how objects in lua work

gaunt thistle
#

an object is a table

frosty dock
#

I have a vscode neovim extension but I've never bothered actually learning the keybinds lmao

edgy reef
#

neovim mentioned?!

gaunt thistle
#

helix is also fun to pick up. it's somewhat similar to vim

#

I always enjoy using it but the terminal experience in windows is still not great

gaunt thistle
frosty dock
#
  • I already have mouse keys
rough furnace
#

assuming I've been given a random object

frosty dock
#

depends on what you mean by a type of object

gaunt thistle
#

^

frosty dock
#

everything is a table first

#

unless it's a primitive

gaunt thistle
#

type() can get you some info but it's not great

rough furnace
gaunt thistle
#

like an oop object?

#

class/struct style

#

eg. an object with functions and data, or an object with just structured data

rough furnace
tepid crow
edgy reef
#

It's in engine/object.lua

valid trench
#

this is literally 1 line but idk why it isn't doing anything

#

I just want to make the Manacle into an Ante 2 boss because I hate them

frosty dock
#

boss = { min = 2 }

valid trench
#

figured

#

I was doing boss: { min = 2 }

#

ty

#

nvm that doesn't work

vapid mango
frosty dock
#

{boss = { min = 2 }}

valid trench
#

ah

#

I'm stupid mb

#

ty

vapid mango
storm oar
#

it might not be set up right

#

could be weirdness with it being animated as well

dense geyser
#

I didn't think Balatro needed a dark mode.. until I saw that. The theme looks cool!

gaunt thistle
#

I liked the voiceover

#

more people need to do that

vapid mango
#

Things seems fine within the file itself

#

nothing changes with the jittering when i change the py value, however

#

i even have it set to the full sprite sheet size rn and it's still doing that

bitter sand
#

guys i'm making consumables and i want them not to be used immediately but instead to keep them in your consumables slots (like alchemical cards from ca)

storm oar
# vapid mango

also are you like directly messing with the game's files for everything else? cause that could mess with other mods as well, iirc cryptid changes values for the background vortex thing

vapid mango
#

mope

#

nope

#

Nothing direct in any way shape or form

rough furnace
frosty dock
#

SMODS classes always have a set

#

-# Balatro classes don't

storm oar
#

also id see if the atlas size is set right by finding the info for the shop sprite in the game's code

vapid mango
#

I'll take another dive tho

storm oar
#

just do a search through every file for shop_sign

spiral stirrup
#

So, as a test to learn how enhancements work, I want an enhancement that adds a red seal to itself after the hand has been scored. this isn't working, and I assume it's because I am using wrong contexts </3

  key = 'fungal',
    loc_txt = {
      name = 'Fungal',
      text = {
        "my beautiful spores"
      }
    },
    config = {extra = {mult = 12, size = 4}},
    loc_vars = function(self, info_queue, card)
      return {vars = {card.ability.extra.mult, card.ability.extra.size}}
    end,
    atlas = 'casssilly',
    pos = {x = 0 , y = 2},
    calculate = function(self, card, context)
      
      if context.after and context.cardarea == G.play then
        
        card = card

        G.E_MANAGER:add_event(Event({
          func = function()
              
              play_sound('gold_seal')
              card:juice_up(1, 0.5)
              card:juice_up(1, 0.5)
              card:set_seal("Red", true)
          return true end }))
          card_eval_status_text(card, 'extra', nil, nil, nil, {
              message = "Seal!",
              colour = G.C.RED
          })

      end
    end
}```
#

ignore the variables and config, I copied some properties from a joker I forgot to remove

edgy reef
#

context.after doesn't exist for enhancements iirc.

#

Kinda sad cause I also need it for my stuff

fallen tendon
#

how do i put a sticker in an info queue?

spiral stirrup
stray warren
edgy reef
#

Probably

faint yacht
#

...are the Mime-like repetitions for cards locked to 1? Trying to return a higher value, in this case, 3.

local repeats = card.ability.extra.repetitions -- is 3.
if context.cardarea == G.hand and context.individual then
  return {
    message = localize('k_again_ex'),
    repetitions = repeats,
    card = card
  }
end
storm oar
#

if so maybe can see how it repeats and just manually do it more times

stray warren
wintry solar
#

It should support more than 1 yeah, hanging chad does 2 in vanilla

storm oar
#

can you implement custom unlock conditions for things?

bitter sand
#

that might be my fault you though i asked something else

teal estuary
#

i cant remember it exactly, but i know you can

faint yacht
#

context.repetition did do it, but I still need to catch if a card doesn't have any effects to trigger... card_effects, was it?

teal estuary
#

this is gonna sound patronising and i dont mean it that way, does mime’s code use it?

faint yacht
#

... and (next(context.card_effects[1]) or #context.card_effects > 1)... so yes.

wintry solar
earnest zealot
#

Mime retriggers actually have a bug in that they won’t retrigger the card if it doesn’t have an effect that triggers the first (like if reserved parking fails the first 1 in 2, it won’t retrigger to roll the second 1 in 2)

storm oar
#

that sounds intentional though

#

because it retriggers the effect

wintry solar
#

it depends what's triggering

#

some are recalculated

storm oar
#

are they specifically mentioned in the code?

earnest zealot
#

They will retrigger the reserved parking if the card has some other unrelated effect

bitter sand
earnest zealot
storm oar
#

ah hmm

faint yacht
#

Not sure how else to reach card_effects to prevent the again spam.

#

Besides using a check if the card is enhanced or has a seal applied.

wintry solar
#

what are you trying to do exactly?

faint yacht
#

Prevent retriggering a playing card without any effects when held in hand.

wintry solar
#

and by effects you mean enhancements, seals and editions?

rough furnace
#

What about also joker effects

faint yacht
#

I just want a Mime-like behaviour.

#

'cause this technically works, even if the again-retrigger appears whether the retrigger did anything or not (i.e. Blue Seals giving planet cards just fine, but it still appears when cons. slots are full.)

if context.cardarea == G.hand and context.other_card and (context.other_card.ability.set == 'Enhanced' or context.other_card.seal) then
  if context.repetition or (context.end_of_round and not context.repetition and not context.individual) then
    return {
        message = localize('k_again_ex'),
        repetitions = repeats,
        card = card
    }
  end
end
stray warren
#

Btw you don't technically need to check for and not context.repetition in those parentheses since you checked for it in the first part of the if statement

storm oar
#

should i make it so that the aura effect for reincarnated cards shows when cards are flipped as well or only if they're front facing?

valid trench
#

I'm trying to use the DeckSkinTemplate.lua and it's not working, like it's not using the texture just the default one, the texture rn is just the among us skin just to get it to work and it isn't

#

like if the texture is too small it will get mad but it doesn't show up

#

so it's obviously reading it just not using it for some reason

storm oar
#

do you have the atlas set up right?

#

and do you have a 1x and 2x version?

valid trench
#

I didn't edit anything about the DeckSkinTemplate.lua besides the file names which are correct

#

yes

storm oar
#

how many are you trying to replace?

#

like ranks-wise

#

and do you have the right number of cards in the image?

valid trench
#

I'm just using the Among Us ones as a base till it works

storm oar
#

hm

valid trench
#

It's really bothering me because it's obviously reading the file but not using it for some reason

storm oar
#

maybe a format issue?

#

and you do have 1x and 2x versions right?

valid trench
#

yes

#

I do

rough furnace
#

do you actually define the atlas?

spiral stirrup
#

Oh I know this one! For some reason, you need to use an atlas that contains every card when setting up a Deckskin

valid trench
#

I just directly copied DeckSkinTemplate.lua from the example mods folder and edited the stuff that's listed as to edit

spiral stirrup
#

i was stuck on this for a while too

valid trench
#

so use 8bitdeck.png

#

ah

spiral stirrup
#

this is what I used, and it worked

storm oar
#

why does it need every card even if you aren't replacing every card???

valid trench
#

fun

spiral stirrup
#

with a deckskin

#

but it's an optional thing

valid trench
#

It's funny I actually started with the full deck png and then changed it because I didn't want to use every card lol

#

and it still doesn't work

#

welp

#

getting rid of the prefix_config = {key = false} fixed it

violet void
#

Hi guys is it possible to change the pos of a joker?

spiral stirrup
rough furnace
wintry solar
#

@frosty dock do you have a sticker example I can use for testing?

violet void
#

is there a list for these functions?

#

in case I want to change the name too

rough furnace
#

no things are all over the place

#

for name I think you want to add a second localization key

violet void
#

yes but how would I assign it to the card

rough furnace
#

I forgor

#

theres something you need to do in loc_vars I belive

violet void
#

alr, thanks for the help

rough furnace
frosty dock
wintry solar
#

oh that's true

obsidian fjord
#

How on earth do I remove a playing card from the full deck, whenever I use :start_dissolve() it removes it but then when the round is over it draws 52/xx and then next round if it draws one of the "removed" cards it leads to an empty card slot in the hand that I can't do anything with

rough furnace
#

where are you removing it?

#

certain calculate things cause ghost cards

obsidian fjord
#

Wdym by where

frosty dock
#

if you're removing with a joker, you should use context.destroying_card

obsidian fjord
#

Oh, you're right

#

I forgot I changed my context after trying to fix some other bug that ended up being unrelated

rough furnace
#

We should maybe add a common pitfalls page to the wiki

#

would be nice for linking

obsidian fjord
#

Lol

frosty dock
#

yeah

rough furnace
#

I can't remeber any other pitfalls off the top of my head

obsidian fjord
#

Well I knew I should use that but I thought it lead to some other bug, and forgot to change it back after fixing that

fallen tendon
#

how do i make a sticker not show up in the collection?

#

and have it only show up in a seperate tab of the collection

#

actually how do i even make a seperate tab of the collection period

#

one that goes in the other category

frosty dock
#

SMODS.current_mod.custom_collection_tabs()

rough furnace
#

oh yeah aure how do I add more than one config tab for my mod

#

(I have too much confiuration)

edgy reef
#

Add the other tab as a extra_tab

frosty dock
#

SMODS.current_mod.extra_tabs()

#

should really doc these

rough furnace
#

yes

#

config_tab is documented

frosty dock
#

i mean mod funcs in general

rough furnace
#

I documented one of them

fallen tendon
#

this is so much pain

#

can we please have base SMODS.ObjectTye aybe have an option to create a misc collection page?

#

you can leave it off if you are making more behind the scenes object types

rough furnace
#

look how card sleeves does it

fallen tendon
#

ok

wintry solar
#

would auto making a page work well?

frosty dock
#

this is what we do for consumable types

#

at least for collections of cards we have util for it now

rough furnace
#

I imagine more other types don't have a good way to represent them that is just able to be dropped in

wintry solar
#

but with custom objects you don't know what they are

#

so how would you draw them?

frosty dock
#

generic object types can't have a generic collection, I don't think

fallen tendon
#

hmm

#

yeah

#

unless maybe if its a modifier to a card it generates a blank card?

#

and then aplies the modifier

wintry solar
#

there's no util application function though

frosty dock
fallen tendon
#

you could also just make SMODS.CollectionPage a thing

frosty dock
#

this is all we need for stickers now

#
  • the reference in other tab
fallen tendon
#

honestly im probably not going to make a special tab for the studs

#

i however will keep the object type since the pool could be useful

teal estuary
#

oh eremel, question, when the enhancement calc is merged will i need to change the effect.repetitions to the usual return function?
-# i wasnt sure wether to ping you or not

frosty dock
#

-# don't ask me why the card areas have a height of 1.03

teal estuary
frosty dock
teal estuary
#

they’re what

edgy reef
#

How would the UI work then?

frosty dock
#

don't ask me, I'm not trying to make one

#

nor am I trying to find an excuse for it

fallen tendon
#

i actually do think that we could divorce it from object types actually

#

we could make a SMODS.CollectionPage that then has a reference to the pool, in addition to a bunch of other options

teal estuary
#

that sounds cool

frosty dock
#

i don't know what that would even want to be capable of

#

collection pages are just arbitrary UI that probably has more than one page

teal estuary
#

True

frosty dock
#

and I already made a util function for collection pages that have cards

#

everything else is too unique for me to cover or care about

teal estuary
#

cool, ty

frosty dock
#

-# i should specify non-fake cards, technically my blind collection objects are also cards

fallen tendon
#

can we just accept that ui code is the tenth ring of hell?

#

my brain hurts

edgy reef
#

It already was a long time ago

#

Only a few can master the dark arts

violet void
thorny adder
#

I cant hear you well

frosty dock
#

-# no

wooden nexus
frosty dock
#

👀

wooden nexus
#

I hueshifted a little so you can see them like in balatro but behold, the Alternative suits

#

There will be a smeared joker that has all modded suits however the original will stay as is because of the enhancements

sturdy compass
#

Why does this message not get sent? The game doesn't crash either, it just doesn't go off for some reason

wintry solar
#

what context?

sturdy compass
#

setting_blind

wintry solar
#

doesn't have message returns

sturdy compass
#

Oh I see. I didn't realize different contexts couldn't take message returns

frosty dock
#

onto mod functions

frosty dock
#

-# nobody will notice i actually hid a breaking change in there

teal estuary
#

-# they definitely wont, trust

frosty dock
#

-# it's a rather irrelevant one, previously action got passed G.CONTROLLER which is useless because it's already a global so now it just takes self

storm oar
#

i just had a dumb idea that would be hard to do but cool if it was possible, minigames between antes that can get you free stuff that normally appears in the shop

hardy viper
#

not sure why that would ever be necessary

karmic totem
#

i have a folder for mods but idk how to put mods in it how do i put mods into the folder?

frosty dock
hardy viper
#

its just an easy shorthand tbh

frosty dock
#

we kinda had the same thing a while back with blind funcs passing G.GAME.blind

violet void
#

is there any mod that changes the Joker's name and/or description?

#

I saw one joker that switched bewteen "im so happy" and "im so sad" but I forgot where it was 😮‍💨

#

Since I guess this isn't possible

wintry solar
#

it's so concise

frosty dock
#

amazing

sturdy compass
#

How would I go about changing some functionality of vanilla hand types?

violet void
frosty dock
sturdy compass
#

Neat, thanks

frosty dock
#

or hook/patch the underlying functions get_X_same/get_flush/get_straight if you're after a less invasive change

frosty dock
#

I'm saying you should have two different localization entries

violet void
#

Ah my bad. I didnt mean a "translation" change but more like after X joker activates, then Y joker changes name and description

frosty dock
#

not what i mean either

#

let me explain

#
{
  descriptions = {
    Joker = {
      j_mod_myjoker1 = {
        name = 'Name',
        text = { 'Text' },
      },
      j_mod_myjoker2 = {
        name = 'Different Name',
        text = {'Different text'}
      }
  }
}
#

you can have a setup like this in your language file

#

then you can use loc_vars to choose any of these descriptions

#
loc_vars = function(self, info_queue, card)
  if condition1 then
    return { vars = {'vars for desc1'}, key = self.key..'1' }
  end
  if condition2 then
    return { vars = {'vars for desc2'}, key = self.key..'2' }
  end
end
violet void
#

that looks interesting
if condition1 was G.GAME.isAvailable

and G.GAME.isAvailable changes during a round, would the change apply?

sturdy compass
violet void
frosty dock
#

if you're after straights specifically we have a bit of an issue, Steamodded overrides get_straight and lovely patches on steamodded files are currently broken

sturdy compass
#

Hmm ok. I am going for specific joker presence for this, here's the functionality I'm after. Sadly I'm still very new to this so lovely patches sound a little intimidating

frosty dock
#

just to be sure I understand the effect correctly, you want them to act as the same rank?

sturdy compass
#

This is not my concept, but I believe the idea is same card exactly (so for example a hand of 5 cards containing all evens would register a flush 5)

frosty dock
#

the ranks part is kind of hard if you want them to be able to stand for each even/odd rank at the same time, but if you choose one rank to represent them you can get away with hooking Card:get_id()

#

same exact card seems a bit sketchy given other card modifiers, like how far do you take that

sturdy compass
#

My guess is modifier doesn't apply, just base rank and suit

frosty dock
#

if we reduce it down to just suits, i don't think just making them wild would work because something like 5 same cards shouldn't trigger something like flower pot

sturdy compass
#

I thing adding wild enhancements to the cards kinda ruins the idea anyways

frosty dock
#

quantum enhancements do just let you have the cards act as wild even though they're base cards

sturdy compass
#

I've never heard of these before. What mod is that a part of?

#

Say I went the taking ownership route, would I have to copy over the base functionality to my end?

wintry solar
#

right, so what about sticker calculation on playing cards doesn't work? everything?

frosty dock
#

i haven't thoroughly tested tbh

#

end_of_round definitely didn't work

#

before my trying to get things working, I'm sure nothing about it would have worked at all, given all there was is a patch into Card:calculate_joker that would take over the return value

violet void
frosty dock
#

yeah that seems really strong, removing playing cards is an insanely good effect to have and even get econ for

#

of course it's a limited resource so idk about legendary

#

but no less than rare for sure, could be something like an epic

wintry solar
#

man, when you properly look through the game's code there are so many things in here that do absolutely nothing

frosty dock
#

oh for sure

wintry solar
#

table.insert(cards, G.hand.highlighted[i]) but cards is never used again

#

WHY

frosty dock
wintry solar
#

oh nvm my highlighting was off

storm oar
#

so question, how hard would it be to change the description of a voucher if a specific joker is unlocked?

storm oar
#

oh

frosty dock
#

same principle

storm oar
#

ok that seems simple enough

#

do i need to patch something to disable discarding if certain cards are selected?

#

and also is there a way i can prevent certain jokers from being sold?

violet void
stray warren
#

Something wrong with this for loop? It's giving me an error in my calculate function: for k, v in pairs(G.jokers.cards) do

storm oar
#

what would be the best way to patch that with the lowest chance of breaking other mods if they patch that?

storm oar
frosty dock
#

you do want ipairs instead of pairs here because pairs isn't ordered, but that won't cause errors

stray warren
#

Ok. I tried just the for loop with an empty body but it was still giving an error. I'll send the contexts and stuff in just a minute

wintry solar
#

it needs ipairs anyway

#

card tables aren't key:value, they're index:value

stray warren
#

Ah, makes sense. The error was 'for' limit must be a number

frosty dock
stray warren
#

Here's the full calculate function:

  calculate = function(self, card, context)
    if context.end_of_round and G.GAME.current_round.hands_played == 1 then
      for k, v in ipairs(G.jokers.cards) do
        -- if v.set_cost then
        --   v.ability.extra_value = (v.ability.extra_value or 0)
        --       + (v.sell_cost > card.ability.extra.money_max and card.ability.money_max or v.sell_cost)
        --   v:set_cost()
        -- end
      end

      return {
        message = localize('k_val_up'),
        colour = G.C.MONEY
      }
    end
  end
frosty dock
stray warren
#

Ooh, maybe not. It wasn't very descriptive

wintry solar
#

oh nvm I am dumb, I use pairs on jokers all the time 😆

stray warren
#

Do I need to remove the joker and re-add it for it to work 🤦‍♂️

frosty dock
#

never hurts to try

stray warren
#

Nope, still breaking. I wonder if it has something to do with accessing G.GAME.current_round.hands_played for some reason

#

When I remove that part it seems to work just fine

rough furnace
#

reading a value shouldn't cause issues

storm oar
#

state_events is a vanilla file right?

stray warren
#

yeah

storm oar
#

check that line number in the lovely dumps folder

frosty dock
#

👀

rough furnace
#

should the debug_info be moved here from the utility functions

frosty dock
#

yeah probably, lemme do that

wintry solar
#

hmmm, how should eval_card handle debuffed cards

#

or do we leave it up to developers in calculate functions to check for debuffs

frosty dock
#

i don't think we should

#

that makes debuffed cards not well-defined

#

debuffed cards should just do debuffed things

gaunt thistle
#

you can drop in luajit

#

it breaks mods but the game will run

stray warren
#

oop, I see my mistake. I forgot an extra after ability when accessing my card's money_max field 🤦‍♂️

gaunt thistle
#

if it offers one at all

#

unless I'm being dumb and it's already luajit

#

who knows

#

it's been a long day

frosty dock
#

isn't it already luajit

rough furnace
#

I'm pretty sure it's already luajit

#

thats how blackhole on mac is able to wokr

gaunt thistle
#

it twis

#

like I said, long day

stray warren
wintry solar
#

I think I've got editions going through eval_card properly now too

#

so the playing card part of this (at least in evaluate play) should be pretty much done

sturdy compass
#

I'm currently trying to keep track of retriggers, but checking within context.cardarea == G.hand crashes with this. Any ideas? Am I potentially overcomplicating things for myself?

violet void
#

I might be wrong tho

wooden nexus
merry raven
#

We got context.scoring_hand for checking cards that have scored, but is there a context that checks for cards that are played, not just scored

stray warren
sturdy compass
frosty dock
violet void
frosty dock
#

these last two conditions are equivalent for arrays

violet void
#

I thought so, but they are both present in Mime logic

sturdy compass
#

Would returning repetitions = 0 be valid?

storm oar
#

so patching discarding, should i use a regex match for it?

violet void
wintry solar
#

no, repetitions is for extra repetitions

wintry solar
violet void
# storm oar so patching discarding, should i use a regex match for it?

I added another if after the first one for my use

[patches.pattern]
target = "functions/button_callbacks.lua"
pattern = '''if G.GAME.current_round.discards_left <= 0 or #G.hand.highlighted <= 0 then 
    e.config.colour = G.C.UI.BACKGROUND_INACTIVE
    e.config.button = nil
else
    e.config.colour = G.C.RED
    e.config.button = 'discard_cards_from_highlighted'
end
'''
position = "after"
payload = '''if G.GAME.nof_disable_discard then 
    e.config.colour = G.C.UI.BACKGROUND_INACTIVE
    e.config.button = nil
else
    e.config.colour = G.C.RED
    e.config.button = 'discard_cards_from_highlighted'
end'''
match_indent = true```
#

mm but I guess if another mod modifies the first one then it wont be added

wooden nexus
#

But first, we have to talk about Parallel Universes

storm oar
#

hold up

wooden nexus
storm oar
#

what if

#

that multiverse chess game but balatro

karmic kelp
#

5d balatro with multiverse time travel

#

where you can send cards to different hands

storm oar
#

oh actually that gives me a fun joker idea actually

#

select a card to put back into the deck for a future hand

violet void
#

does playing cards count for
context.remove_playing_cards
?

#

as in they are being removed from the hand

wooden nexus
#

I got an odd question: is it possible to turn the hiker ability into a consumable that i can use on any card i pick?

storm oar
karmic kelp
#

(permanent Hiker-flavored chips too)

wooden nexus
wooden nexus
karmic kelp
#

lemme rip that code out of my current mod then...

wooden nexus
#

oh cool

karmic kelp
#
SMODS.Consumable{
    object_type = "Consumable",
    set = "atomic",
    name = "atomic-silicon",
    key = "silicon",
    atlas = "atomic_atlas",
    pos = {
        x = 6,
        y = 1
    },
    loc_txt = {
        name = "Silicon",
        text = {
            "Gives up to {C:attention}#1#{} selected",
            "cards {C:chips}+#2#{} extra chips"
        }
    },
    cost = 3,
    discovered = true,
    order = 23,
    config = {
        extra = {
            max_highlighted = 2,
            bonus = 10
        }
    },
    can_use = function(self, card)
        return #G.hand.highlighted > 0 and #G.hand.highlighted <= card.ability.extra.max_highlighted
    end,
    use = function(self, card, area)
        for i = 1, #G.hand.highlighted do
            G.E_MANAGER:add_event(Event({
                trigger = 'after',
                delay = 0.4,
                func = function()
                    G.hand.highlighted[i]:flip()
                    play_sound('tarot1', 1.1, 0.6)
                    return true
                end
            }))
        end
        delay(0.2)
        for i = 1, #G.hand.highlighted do
            G.E_MANAGER:add_event(Event({
                trigger = 'after',
                delay = 0.4,
                func = function()
                    local c = G.hand.highlighted[i]
                    c:flip()
                    play_sound('tarot2', 0.9, 0.6)
                    c:juice_up(0.3, 0.3)
                    c.ability.perma_bonus = c.ability.perma_bonus + card.config.extra.bonus
                    return true
                end
            }))
        end
    end,
    loc_vars = function(self, info_queue, center)
        return {vars = {center.ability.extra.max_highlighted, center.ability.extra.bonus}}
    end
}
#

...for future reference should I just DM big code blocks like that?

wintry solar
#

c.ability.perma_bonus = c.ability.perma_bonus + card.config.extra.bonus this is the important bit btw

karmic kelp
#

yeah

wooden nexus
#

ok. lemme try this

#

Just need to figure out how to give it perma_mult I guess

karmic kelp
#

how hard is it to add/replace functionality of a base game enhancement? Is it just claiming ownership and overriding one of the methods?

wintry solar
#

depends which one you want to change

karmic kelp
#

for simplicity I believe I want to modify all of them

#

but all in different ways

merry raven
#
SMODS.Enhancement {
    key = "devour",
    loc_txt = {
        name = "Devour",
        text = {
            "Discarding cards adjacent",
            "to it will grant +5 Mult",
            "Resets when played"
        }
    },
    atlas = 'Enhancements',
    config = { extra = { mult = 0 } },
    pos = {x=1, y=1},
    calculate = function(self, card, context, effect)
        if context.discard then
            for i, handCard in ipairs(G.hand.cards) do
                if handCard == context.other_card then
                    if (i > 1 and G.hand.highlighted[i-1]) or
                       (i < #G.hand.cards and G.hand.highlighted[i+1]) then
                        card.ability.extra.mult = card.ability.extra.mult + 10
                    end
                    break
                end
            end
        end
        if context.cardarea == G.play and not context.repetition then
            if card.ability.extra.mult > 0 then
                effect.mult = card.ability.extra.mult
            end
        end
    end
}

I'm trying to make a new Enhancement where discarding cards adjacent to the Enhanced card grants +10 mult, but it keeps crashing, saying that attempt to index field 'extra' (a nil value)

I'm thinking that it's because mult is 0 in the config section, but the card's supposed to start off at 0 mult before ramping up, and without config, it'll just crash saying that it needs the extra section

wooden nexus
#

could i just do like c.ability.mult?

teal estuary
#

oh on that note, is it just taking ownership of something to change its graphics? i want to change the colour of red seal, but i've never touched take_ownership 😭

violet void
wintry solar
karmic kelp
#

what level of pain? Are we talking lovely patches?

wintry solar
#

lots of lovely patches I would imagine

sturdy compass
karmic kelp
#

hmm... I guess I'll need to study more of my full combination then
because I want to enhance enhancements if they have a certain sticker on the card

wintry solar
merry raven
#

agony

wintry solar
merry raven
karmic kelp
#

at this rate I think I'm going to just release a mod with 26 consumables then...

wooden nexus
#

Lemme see if the chip ones work atm

karmic kelp
#

then focus the jokers

wintry solar
#

I am lost inbetween builds

merry raven
#

I'm still lost on what the nil error means

#

Is it because mult is 0 and it's looking at it as a nil or something

wintry solar
#

which line?

storm oar
#

0 is not a nil value

merry raven
#

Something else is amiss then

wintry solar
#

you can just do if card.ability.extra.mult then if it starts as 0

wooden nexus
#

what's up?

merry raven
wintry solar
#

I don't think you'll ever increment it though, context.discard doesn't have context.other_card

#

no keep the config

merry raven
#

Ah right

#

Yeah it doesn't have a popup saying +10 Mult or something, is that something you have to manually code in or it does so automatically

wintry solar
#

you probably want to use context.pre_discard and check if context.full_hand cards are adjacent to the current card instead

#

it doesn't have any return state though so you'd need to throw your own message

#

-# for now

merry raven
#

For now you say

#

Anyways I'll see what I can do

faint yacht
wintry solar
#

what do you mean by useless retriggers on yours?

faint yacht
#

Not "Mime"... I'm just not sure how to limit the Mime-like retriggers on cards held in hand. Mine currently applies retriggers regardless if the card's enhancement or seal does anything or not. 😅

wintry solar
#

oh yeah this will fix that

merry raven
teal estuary
#

im pretty sure its for things like burnt

#

-# dont quote me on that

#

istg it says on the documentation what jokers use it

wintry solar
#

oh snap vanilla only has it on jokers

#

😢

#
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = "inc_career_stat('c_cards_discarded', highlighted_count)"
match_indent = true
position = "after"
payload = """
for i = 1, #G.hand.cards do
    eval_card(G.hand.cards[i], {pre_discard = true, full_hand = G.hand.highlighted, hook = hook})
end"""
wooden nexus
#

Alright, let's see if this works

wintry solar
#

this is the lovely patch to add it for cards in your hand

wooden nexus
wintry solar
#

wait nvm I can't read

#

it's built in smods

#

it runs just before the discard happens

faint yacht
# wintry solar oh yeah this will fix that

'cause I very much am not sure how to limit it further currently. The card_effects will be available for use with the later release?

if context.cardarea == G.hand and context.other_card and (context.other_card.ability.set == 'Enhanced' or context.other_card.seal) then
  if context.repetition or (context.end_of_round and not context.repetition and not context.individual) then
    return {
      message = localize('k_again_ex'),
      repetitions = repeats,
      card = card
    }
  end
end
wooden nexus
merry raven
#
calculate = function(self, card, context, effect)
        if context.pre_discard then
            for i, handCard in ipairs(G.hand.cards) do
                if handCard == card then
                    if (i > 1 and context.full_hand[i-1]) or
                       (i < #G.hand.cards and context.full_hand[i+1]) then
                        if card.ability.extra.mult then
                            card.ability.extra.mult = card.ability.extra.mult + 10
                        end
                    end
                    break
                end
            end
        end   
        if context.cardarea == G.play and not context.repetition then
            if card.ability.extra.mult then
                effect.mult = card.ability.extra.mult
            end
        end
    end

Yeah I may be a bit lost on how I should implement pre_discard

teal estuary
#

-# it really helps when paired with errors

wooden nexus
#

ok jk

teal estuary
wintry solar
teal estuary
#

not card.config?

#

-# i presume its the same for consumables as it is for jokers, but idk

wintry solar
wooden nexus
#

then changed it

teal estuary
#

wrong emoji, but i mean

#

works

karmic kelp
#

oh I might've screwed up that part of the code

#

at some point I did a transition from basing everything off config to ability, but haven't gone through and tested every card

merry raven
wintry solar
#

I define and use this to check if tables contain a value

function table.contains(table, element)
    for _, value in pairs(table) do
        if value == element then
            return true
        end
    end
    return false
end
merry raven
night pagoda
faint yacht
merry raven
faint yacht
#

Outside entirely, yeah.

merry raven
#

Well, even then it still says attempt to index field 'extra' (a nil value)

function table.contains(table, element)
    for _, value in pairs(table) do
        if value == element then
            return true
        end
    end
    return false
end
...
config = { extra = { mult = 0 } },
    pos = {x=1, y=1},
    calculate = function(self, card, context, effect)
        if context.pre_discard then
            for i, handCard in ipairs(G.hand.cards) do
                if handCard == card then
                    if (i > 1 and table.contains(context.full_hand, G.hand.cards[i-1])) or
                       (i < #G.hand.cards and table.contains(context.full_hand, G.hand.cards[i+1])) then
                        if card.ability.extra.mult then
                            card.ability.extra.mult = card.ability.extra.mult + 10
                        end
                    end
                    break
                end
            end
        end
        if context.cardarea == G.play and not context.repetition then
            if card.ability.extra.mult then
                effect.mult = card.ability.extra.mult
            end
        end
    end
}
#

I'm out of ideas what causes this error except for the config tag

wintry solar
#

Did you give the enhancement to the card before you added the config

wooden nexus
#

I still can't figure out why it's not working

wintry solar
stray warren
#

Is there an easier way than this to make it so that set_cost() doesn't automatically recalculate a card's base cost? For example, I have a joker that resets a card's sell value to 0, but if I want it to go up by 1 after that, it adds the base cost and then + 1 to that.

faint yacht
wintry solar
#

I don’t believe so, nope

faint yacht
#

Fair enough, I'll just mention the jank in the description.

merry raven
wintry solar
#

In game

merry raven
#

Yeah I did
I used the debug tool to set a card to the Enhancement I made, discarded a card next to it (gave no popups), played a Flush with it, and it crashed

wintry solar
faint yacht
#

context.card_effects or context.other_card.card_effects end up as nil, did try.

wintry solar
#

I see

faint yacht
#

Potentially such has not been exposed yet.