#💻・modding-dev

1 messages · Page 525 of 1

willow scroll
#

oh thats a context? neat let me try

#

damn that works thank you very much

final jewel
sturdy compass
#

I also had no clue that was a context 😭

red flower
#

all the blind functions have contexts now basically

#

although it would be nice to have the docs for them :3

umbral zodiac
#

is there a function i can hook to change the cost of anything you have to buy

red flower
#

card:set_cost?

umbral zodiac
#

oh right i forgot lmao

#

ty

wintry solar
#

soonTM

red flower
sturdy compass
#

I mean, set_ability creates a new instance of the ability, does it not? Why would it copy values?

red flower
#

i dont recall if set_ability or copy_card but one of those keeps the values of the original

#

i mean, copy_card does but i dont remember if it's set_ability's doing

#

the problem is not that theyre being reset, its that they're being upgraded

sturdy compass
#

I wonder, does it carry over the ability table before or after the set_ability call?

final jewel
#

Its like they are being rounded but their is only 2 digits so thats make 0 sense

sturdy compass
#

If it’s before, that’s probably why and is a fundamental error in base code lmao

fossil nebula
#

.

knotty orchid
#

I want the buttons (and area) to draw above every other area so they don't collapse with consumables f.e.
I've tried increasing draw_layer but all it does is disappear

Pokerleven.create_UIBox_bench_area = function()
    local t = {
        n = G.UIT.ROOT,
        config = { align = 'cm', r = 0.1, colour = G.C.CLEAR, padding = 0.02 },
        nodes = {
            {
                n = G.UIT.O,
                config = {
                    object = Pokerleven.ina_bench_area,
                    draw_layer = 1
                }
            },
        }
    }
    return t
end
red flower
#

where are you defining the area?

knotty orchid
#
self.ina_bench_area = CardArea(
        0,
        0,
        self.CARD_W * 4.95,
        self.CARD_H * 0.95,
        {
            card_limit = 4,
            type = 'joker',
            highlight_limit = 1,
        }
    )
    Pokerleven.ina_bench_area = G.ina_bench_area
red flower
#

where

knotty orchid
#

hooked inside Game:start_run

red flower
#

before or after the reference call

knotty orchid
#
local game_start_run_ref = Game.start_run
function Game:start_run(args)
    self.ina_manager_area = CardArea(
        0,
        0,
        self.CARD_W * 1.9,
        self.CARD_H * 0.95,
        {
            card_limit = 1,
            type = 'joker',
            highlight_limit = 1,
        }
    )
    Pokerleven.ina_manager_area = G.ina_manager_area

    self.ina_bench_area = CardArea(
        0,
        0,
        self.CARD_W * 4.95,
        self.CARD_H * 0.95,
        {
            card_limit = 4,
            type = 'joker',
            highlight_limit = 1,
        }
    )
    Pokerleven.ina_bench_area = G.ina_bench_area

    game_start_run_ref(self, args)
red flower
#

is this the consumable area or the manager area

knotty orchid
#

The consumable

red flower
#

hmm

#

i think it should be working like that

wispy falcon
#

Is there something for changing the sprite of a joker, when a requirement is met?

knotty orchid
#

This is the hole code of start_run

local game_start_run_ref = Game.start_run
function Game:start_run(args)
    self.ina_manager_area = CardArea(
        0,
        0,
        self.CARD_W * 1.9,
        self.CARD_H * 0.95,
        {
            card_limit = 1,
            type = 'joker',
            highlight_limit = 1,
        }
    )
    Pokerleven.ina_manager_area = G.ina_manager_area

    self.ina_bench_area = CardArea(
        0,
        0,
        self.CARD_W * 4.95,
        self.CARD_H * 0.95,
        {
            card_limit = 4,
            type = 'joker',
            highlight_limit = 1,
        }
    )
    Pokerleven.ina_bench_area = G.ina_bench_area

    game_start_run_ref(self, args)

    Pokerleven.ina_manager_uibox = UIBox {
        definition = Pokerleven.create_UIBox_manager_area(),
        config = {
            align = 'cmi',
            offset = { x = 2.3, y = 3.5 },
            major = self.consumeables,
            bond = 'Weak'
        } }

    self.ina_bench = UIBox {
        definition = Pokerleven.create_UIBox_bench_area(),
        config = { align = 'cmi', offset = { x = 0, y = -5 }, major = self.jokers, bond = 'Weak' }
    }
end
red flower
red flower
wispy falcon
red flower
#

not a different atlas if thats what you mean

#

for a different atlas it's more complicated

sturdy compass
#

Time to change that! areyoustupid

knotty orchid
#

They appear behind any area

red flower
#

i fixed that issue with the draw_layer = 1

wispy falcon
red flower
red flower
#

thats what i sent

#

you would put it in the same atlas and change the pos

knotty orchid
wispy falcon
red flower
#

yes

wispy falcon
#

I'm gonna try it, thank you :)

knotty orchid
#

the sell custom button

red flower
#

maybe

rocky plaza
#

alright if i want to have a spectral card have a 0.3% chance to replace a playing card in a standard pack, what would be the best approach?

pastel kernel
#
    calculate = function(self, card, context)
        if context.individual and context.cardarea == G.play  then
            if context.other_card:get_id() == 14 then
                return {
                    x_mult = card.ability.extra.acemult,
                }
            end
            local chance = pseudorandom('susies_idea')
            if chance < G.GAME.probabilities.normal / card.ability.extra.aceodds then
                SMODS.add_card{ set = "Base", rank = "A", enhancement = "m_steel", edition = "e_polychrome", seal = "Red" }
            end
        end
    end```
#

why does this not give xmult

rocky plaza
fossil nebula
#

i don't get pseudorandom

#

I want it to give me a number between 1 and 5

#

and then do something based on that

#

how can i do that

rocky plaza
#

pseudorandom("seed", 1, 5) i think

fossil nebula
#

yeah but then how do i get the number it generated

frosty rampart
#

it's a function call, and it returns the number it generated

red flower
#

local number_generated = pseudorandom("seed", 1, 5)

knotty orchid
red flower
#

it took me 3 months to find the solution myself so good luck

umbral zodiac
# rocky plaza ^

set the soul_rate to 0.3 and then set the soul_set to Standard(?)
not really sure of the soul_set variable exactly, but thats how you get it to generate in other packs

knotty orchid
#

I think i'm just gonna set the last card buttons on the left

#

fk it

subtle merlin
#

Bump

red flower
# subtle merlin Bump

depends on the event
for preventing death i think you would need to patch the code that does that

subtle merlin
#

Uuuggggghhhhhhh yay, more patches

#

I'll try to see if I can figure out patching for this, ty

knotty orchid
#

Are there any examples of this config for UI?
instance_type: set the layer that the current node is drawn on, either:
NODE, MOVEABLE, UIBOX (w/o attention_text), CARDAREA, CARD, UI_BOX (w/ attention_text), ALERT, or POPUP
These are ordered from lowest to highest layer.

#

maybe thats what I need

red flower
#

you can just try them out

pastel kernel
#

Today I learn the difference between Xmult and x_mult

red flower
#

i did and it made stuff render over other stuff i didn't want

red flower
knotty orchid
#

instance_type is a sub config parameter right?

red flower
#

it's a parameter for the uibox's config

pastel kernel
#

Today I learn I’m an idiot

#

Ok then why does playing a high card lose the xmult?

knotty orchid
#

So something like this right?
lua self.ina_bench = UIBox { definition = Pokerleven.create_UIBox_bench_area(), config = { align = 'cmi', offset = { x = 0, y = -5 }, major = self.jokers, bond = 'Weak', instance_type = "UI_BOX" }, }

pastel kernel
#

Photograph too??

knotty orchid
#

Okay

#

It does something

#

extrange

#

hahaha

#

I mean it works but...

pastel kernel
#

this does not work?lua calculate = function(self, card, context) if context.individual and context.cardarea == G.play then if context.other_card:get_id() == 14 then return { Xmult = card.ability.extra.acemult } end local chance = pseudorandom('susies_idea') if chance < G.GAME.probabilities.normal / card.ability.extra.aceodds then SMODS.add_card{ set = "Base", rank = "A", enhancement = "m_steel", edition = "e_polychrome", seal = "Red" } end end end

red flower
pastel kernel
knotty orchid
#

Finally

pastel kernel
#

1 in 10 chance to also spawn random red seal steel polychrome ace during scoring any card

red flower
#

then you need to return at the end after you add the card

red flower
knotty orchid
#

Maybe you can use UI_BOX also as its above cardarea

red flower
# pastel kernel Wdym

when you return from a function it ends
so if the card is an ace it won't try to add

pastel kernel
#

So let me try to comprehend that

#

The only function I see in here is in calculate

#

When you return from a function it ends

#

So

#

Ok I got nothing

red flower
#

do you see the return keyword

#

when it reaches that calculate immediately ends

pastel kernel
#

So I also have to add a return end in the pseudorandom thing?

#

or do i try to fit it in?

red flower
#

you need to move that if condition to the end

pastel kernel
#

Ah

#

So

#

Checking ace snippet is instead moved right under polychrome ace snippet

red flower
#

yes

pastel kernel
#

Now I have a different problem, why does multiplying 1 by xmult stay at 1?

#

This happened with susie

#

Spinel

#

And even photograph

red flower
#

i dont get what you mean

pastel kernel
red flower
#

no idea

pastel kernel
#

Photograph is a vanilla joker, it should work

red flower
#

that seems like a mod messing with calculation

pastel kernel
#

Also uh

#

Chance is unriggable

#

Tried seeding it

red flower
#

i would ask ruby

pastel kernel
#

oops all 6s works

wind steppe
chrome widget
#

Wdym by unriggable?

wind steppe
#

use the new probability system

red flower
#

oh rigged probably uses the new system yeah

chrome widget
#

Oh yeah you can probably just replace it with the fix_probability context

pastel kernel
#

Which is?

red flower
chrome widget
#

Oh if it's cryptid idk if it's updated to use it yet

pastel kernel
#

Rigged sticker makes all probabilities guaranteed

red flower
#

yeah you should update to the new probability method

pastel kernel
wind steppe
wind steppe
chrome widget
#

I'm aware old cryptid probability rigging was jank as all fuck

wind steppe
#

tutorial there

pastel kernel
#

Oops all 6s works tho

chrome widget
#

Oops is hardcoded

wind steppe
red flower
#

oops all 6s is hardcoded to work for back compat

pastel kernel
chrome widget
#

Ough not looking forward to doing Cryptid compatibility tbh

red flower
#

my mod is just not compatible :3

chrome widget
#

Bone to pick with cryptid and talisman for being so popular and getting in early, making other mod compatibility expected

wind steppe
#

If Cryptid (not talisman) isn't compatible with your mod it's cryptid's fault

pastel kernel
#

local new_numerator, new_denominator = SMODS.get_probability_vars(card, numerator, demoninator, 'identifier')

#

what do i write in place of identifier

#

also do i keep numerator and denominator as such?

#

demoninator

#

demon-inator

red flower
#

identifier should probably be the seed string you are using

wind steppe
#

your numerator and denominator respectively should be there

willow scroll
#

im having trouble finding how function SMODS.debuff_card(card, debuff, source) works. can someone explain how to usedebuff and source?

wind steppe
#

so probably 1 and card.ability.extra.odds

pastel kernel
#

return {vars = {G.GAME.probabilities.normal, card.ability.extra.aceodds, card.ability.extra.acemult}}

willow scroll
wind steppe
#

new_numerator, new_denominator, and card.ability.extra.acemult

pastel kernel
wind steppe
wind steppe
#

not required but it is good practice

pastel kernel
#

busterb_susies_idea omfg i'm gonna bang my head against the wall that is a mouthful

red flower
willow scroll
pastel kernel
#

wait wtf

wind steppe
#

seven characters is far too much

crystal perch
#

anybody know why SMODS.load_file isn't working?
it doesn't throw any errors when loading but the jokers can't seem to find the atlases despite me calling for it to load

pastel kernel
#

this

loc_vars = function(self, info_queue, card)
  local new_numerator, new_denominator = SMODS.get_probability_vars(card, 1, demoninator, 'busterb_susies_idea')
  return {vars = {new_numerator, new_denominator, card.ability.extra.acemult}}
  end,
  calculate = function(self, card, context)
      if context.individual and context.cardarea == G.play and not context.blueprint then
          local chance = pseudorandom('busterb_susies_idea')
          if chance < G.GAME.probabilities.normal / card.ability.extra.aceodds then
              SMODS.add_card{ set = "Base", rank = "A", enhancement = "m_steel", edition = "e_polychrome", seal = "Red" }
end
        ```
red flower
wind steppe
crystal perch
wind steppe
#

but the loc_vars is good

crystal perch
#

at least last time i tried

#

i'll update smods and try again

red flower
crystal perch
#

no there's definitely a file there and the code worked previously when it was just in main

pastel kernel
red flower
#

post the crashlog

crystal perch
#

it's attempting to call a nil value

wind steppe
subtle merlin
crystal perch
#

line 21 is the load_file btw

wind steppe
red flower
wind steppe
crystal perch
#

it looks like it cant read it

red flower
#

yeah the path is wrong

wind steppe
crystal perch
#

oh wait one moment

#

i may have been editing it in the wrong place 💀

#

nope i moved it to roaming and it still errors out

#

let me do something

#

okay i figured it out

pastel kernel
#

i made the seed an identifier...

crystal perch
#

my VSC was open in the wrong filepath so i was unknowingly editing the incorrect files

#

looks like i gotta change my workspace preset

pastel kernel
#

the pseudorandom seed was susies_idea

#

the identifier is busterb_susies_idea

wind steppe
#

seed should also be busterb_susies_idea

wind steppe
#

demoninator should be your denominator for the probability

pastel kernel
#

which is aceodds

#

right?

wind steppe
pastel kernel
#

like in here?
return {vars = {acechance, aceodds, card.ability.extra.acemult}}
replace aceodds with card.ability.extra.aceodds?

wind steppe
pastel kernel
#

SMODS.get_probability_vars(card, 1, card.extra.ability.aceodds, 'busterb_susies_idea')

pastel kernel
#

local chance = pseudorandom('susies_idea')
if SMODS.pseudorandom_probability(card, 'susies_idea', 1, card.extra.ability.aceodds, 'busterb_susies_idea') then

wind steppe
#

and then your return should be return {vars = {new_numerator, new_denominator, card.ability.extra.acemult}}

pastel kernel
#

how about this?

wispy falcon
#

Why does this happen?

    
    if context.before and context.cardarea == G.jokers then
        card.ability.extra.card_amount = 0

        for _, c in ipairs(context.scoring_hand) do
            if context.other_card.edition and context.other_card.edition.key == "e_foil" then
                card.ability.extra.card_amount = card.ability.extra.card_amount + 1
            end
        end
    end

    if context.joker_main and context.cardarea == G.jokers and card.ability.extra.card_amount > 0 then
        return{
            chips = card.ability.extra.chips * card.ability.extra.card_amount
        }
    end
end,```
pastel kernel
wind steppe
red flower
wind steppe
pastel kernel
#

yes

wind steppe
wispy falcon
wind steppe
pastel kernel
#

seed and identifier use the same key 💔

red flower
wind steppe
#

what are you trying to do

#

because it looks like permabonuses might be the answer to your problem

wind steppe
pastel kernel
#

what do i do here now
local chance = pseudorandom('busterb_susies_idea')

wind steppe
#

the age of pseudorandom is dead

pastel kernel
#

final

    loc_vars = function(self, info_queue, card)
    local acechance, aceodds = SMODS.get_probability_vars(card, 1, card.extra.ability.aceodds, 'busterb_susies_idea')    return {vars = {acechance, aceodds, card.ability.extra.acemult}}
    end,
    calculate = function(self, card, context)
        if context.individual and context.cardarea == G.play and not context.blueprint then
            if SMODS.pseudorandom_probability(card, 'busterb_susies_idea', 1, card.extra.ability.aceodds, 'busterb_susies_idea') then
                SMODS.add_card{ set = "Base", rank = "A", enhancement = "m_steel", edition = "e_polychrome", seal = "Red" }
            end```
wispy falcon
wind steppe
pastel kernel
wind steppe
#

then thats perfect

wind steppe
#

pick one

wispy falcon
pastel kernel
#

guess i'll have to change my other chance joker peacock

wind steppe
# wispy falcon scored

in context.individual check if the cards foil and increase card.ability.extra.card_amount (like youre doing in the for loop)

hallow slate
#

Is putting vouchers and boosters in consumable slots possible

wind steppe
hallow slate
#

Oh shit really?

wind steppe
pastel kernel
#

like this too?```lua
loc_vars = function(self, info_queue, card)
local polychance, polyodds = SMODS.get_probability_vars(card, 1, card.extra.ability.odds, 'busterb_peacock_polychrome')
return {
vars = {
card.ability.extra.SA2XChips,
card.ability.extra.SA2XMult,
card.ability.extra.SA2Mod,
polychance,
polyodds
}
}
end,

calculate = function(self, card, context)
    if context.individual and context.cardarea == G.play and not context.blueprint then

        local is_polychrome = context.other_card.edition and context.other_card.edition.polychrome
        if is_polychrome then
            card.ability.extra.SA2XChips = card.ability.extra.SA2XChips + card.ability.extra.SA2Mod
            card.ability.extra.SA2XMult = card.ability.extra.SA2XMult + card.ability.extra.SA2Mod
            card_eval_status_text(card, 'extra', nil, nil, nil,
                { message = localize("k_upgrade_ex"), colour = G.C.PURPLE })
            return { card = card }
        else
            if SMODS.pseudorandom_probability(card, 'busterb_peacock_polychrome', 1, card.extra.ability.odds, 'busterb_peacock_polychrome') then
                context.other_card:set_edition({ polychrome = true }, true)
                card.ability.extra.SA2XChips = card.ability.extra.SA2XChips + card.ability.extra.SA2Mod
                card.ability.extra.SA2XMult = card.ability.extra.SA2XMult + card.ability.extra.SA2Mod
                card_eval_status_text(card, 'extra', nil, nil, nil,
                    { message = localize("k_upgrade_ex"), colour = G.C.PURPLE })
            else
            end```
wind steppe
wind steppe
split saddle
#

how would one go about retriggering jokers? i'd check cryptid's code but i was advised against it xd

wind steppe
#
    retrigger_joker = true,
}```
pastel kernel
#

Our crossmod joker 🥀

wind steppe
#

put that at the top of your main file

wind steppe
pastel kernel
knotty orchid
#

How do I know if I'm inside a blind?

pastel kernel
#

the only rare joker i've made atm is susie's idea

wintry solar
wind steppe
wind steppe
knotty orchid
#

Nop. In a can_use. I want to disable a button inside blinds

pastel kernel
#

and the line in question is

     local acechance, aceodds = SMODS.get_probability_vars(card, 1, card.extra.ability.aceodds, 'busterb_susies_idea')
wintry solar
pastel kernel
#

apparently it's attempting to index field 'extra'

wind steppe
knotty orchid
#

That's nice to know

#

thanks

wind steppe
pastel kernel
wispy falcon
#

I think I did it wrong... Now the Joker does nothing at all

    
    if context.before and context.cardarea == G.jokers then
        card.ability.extra.card_amount = 0
    end

    if context.individual and context.cardarea == G.jokers then
        for _, c in ipairs(context.scoring_hand) do
            if context.other_card.edition and context.other_card.edition.key == "e_foil" then
                card.ability.extra.card_amount = card.ability.extra.card_amount + 1
            end
        end
    end

    if context.joker_main then
        return{
            chips = card.ability.extra.chips * card.ability.extra.card_amount
        }
    end
end,```
split saddle
#

i assume it would be something like context.joker_main and context.repetition but idk

wintry solar
#

However

wind steppe
wintry solar
#

For this joker I wouldn’t use context.individual at all

#

You just need to iterate over context.scoring_hand within your joker main check and keep a local count of the number of foil cards

split saddle
wind steppe
wind steppe
#

shits undocumented so i have to go off of cryptid and only cryptid

split saddle
#

lmao ok

wind steppe
split saddle
#

jokers next to this one

wind steppe
#

that implies retrigger synergy

wintry solar
#

N do you have all my new doc screenshots saved or something

knotty orchid
# wind steppe G.hand and G.GAME.blind.in_blind returns true if and only if youre in a blind

Doesn't seem to work. I can still use the button inside a blind

G.FUNCS.can_toggle_bench_card = function(e, area, button_name, active_colour)
    if area.config.card_count >= area.config.card_limit and G.GAME.blind.in_blind then
        e.config.colour = G.C.UI.BACKGROUND_INACTIVE
        e.config.button = nil
        return false
    else
        e.config.colour = active_colour
        e.config.button = button_name
        return true
    end
end```
split saddle
wintry solar
red flower
knotty orchid
#

yeah I tried that too

wind steppe
knotty orchid
#

doesn't work either

wind steppe
#

vague wording ig

pastel kernel
#

THE PROBABILITY WORKS

wind steppe
modern kindle
#

holy shmoly is that eremel hi eremel

wintry solar
#

Hello dilly

modern kindle
#

i hope you fare well this day

pastel kernel
wintry solar
#

I do fare well I hope you also fair well

wispy falcon
#

So what should I try now? context.individual or something else?

modern kindle
red flower
wintry solar
wind steppe
#

update smods?

wispy falcon
wispy falcon
wind steppe
#

those retriggers

#

if a foil card is retriggered, should it add +15 chips again

knotty orchid
hardy ibex
#

did you find a way to do it?

knotty orchid
#

still doesn't work 🙁

wispy falcon
wind steppe
wind steppe
thorn furnace
wind steppe
#

also do you want this to reset or not

knotty orchid
#

Yep

#

i can use it anywhere

hardy ibex
wind steppe
knotty orchid
crystal perch
#

getting a problem where one of my functions for registering items errors out at line 7 where it's attempting to call a nil value. all the files & paths exist and are named properly and are loaded into main, so i don't understand the issue

wispy falcon
knotty orchid
crystal perch
wind steppe
wind steppe
#

G.GAME should do?

crystal perch
#

commenting out counterfeit joker made it work

#

i may be an idiot

red flower
#

it says it in the log btw

willow scroll
#

wait is card.rank from G.playing_cards not the same as the rank?

hardy ibex
red flower
crystal perch
willow scroll
wind steppe
#

just hook whatevers called when you sell a joker

#

idk the exact function

chrome widget
#

Hey Dilly, you interested in being a mod playtester?

knotty orchid
#

If I want to add an uibox to the right of the deck, what is the major? G.deck?

hardy ibex
wind steppe
hardy ibex
#

Ill check it

wind steppe
#

does anyone here want to explain hooks?

#
Klei Entertainment Forums

In LUA, it is a very important concept to understand that everything is a variable and all variables may be edited in runtime. This includes functions. With modding other peoples' LUA files, like Klei's basegame code, you may find yourself wanting to run your code before or after the original fun...

hardy ibex
#

Ty, appreciate 🙏

rocky plaza
#

essentially hooking is just storing a function as a variable under a different name, then overriding it by creating a new function with the exact same name
then in your new function somewhere call (and return if necessary) the original function with the new name and the original arguments
And now you have the power to do stuff before and after the function is called

rocky plaza
#

i.e

local start_run_hook = Game.start_run
function Game:start_run(args)
    start_run_hook(self, args)
    G.GAME.glass_broken = G.GAME.glass_broken or {}
end
violet oasis
#

If I set up two music tracks with SMODS.Sound, where Music 1 has conditions A and B and Music 2 has conditions A, B and C, and I have conditions A, B and C currently fulfilled (making Music 2 play), does that actively stop Music1 or does it keep "playing" in the background? If condition C goes away and Music 1 comes back, will it start from the beginning or will it be midway through as if it was playing the whole time?

rocky plaza
hardy ibex
#

So if i have to get the last joker sold ill have to create a hook and create a new variable (for example G.GAME.last_joker_sold) that stores the id of the last sold joker?

rocky plaza
#

yeah

hardy ibex
#

And then i can use this new variable when in the consumable code

rocky plaza
#

yep

hardy ibex
#

I understand it now

#

Ill try, ty so much

rocky plaza
#

gotta do a nil check tho to make sure that a joker has been sold before

faint yacht
#

Funny, but scrapped.

rocky plaza
violet oasis
# violet oasis If I set up two music tracks with SMODS.Sound, where Music 1 has conditions A an...

I've been having trouble with this setup. If I activate the enable_fast_music setting it switches to the 2nd track, but when I deactivate it and it goes back to the 1st track it doesn't start at the beginning. It's like if it's just muting one and unmuting the other instead of restarting the tracks. I also tried setting different priority values, but it didn't do much. Am I missing something?

    vol = 0.6,
    pitch = 0.8,
    key = "music_middle_normal",
    path = "middleNormal.ogg",
    select_music_track = function()
        return (G.GAME.selected_back.name == 'The Middle Deck' and G.GAME.blind and not G.GAME.blind.boss and not G.shop and not ProjectMoonMusic.config.enable_fast_music) and 0 or false
    end,
})

SMODS.Sound({
    vol = 0.6,
    pitch = 1.0,
    key = "music_middle_normal_f",
    path = "middleNormal.ogg",
    select_music_track = function()
        return (G.GAME.selected_back.name == 'The Middle Deck' and G.GAME.blind and not G.GAME.blind.boss and not G.shop and ProjectMoonMusic.config.enable_fast_music) and 0 or false
    end,
})```
rocky plaza
brittle yacht
#

OK

#

oops caps loc

knotty orchid
#

If I want to create a new Sprite for a G.UIT.O. Should I use SMODS.Sprite? And how does it work?

brittle yacht
#

how do i create a joker that does something when a glass card is clicked

wintry solar
knotty orchid
#

And how does that work? Can I reference an atlas from it?

wispy falcon
#

How do you use card.children.center:set_sprite_pos({x = x, y = y})? Like when and what for?

violet oasis
wintry solar
distant junco
#

how do i do the effect of a legendary joker and have the art seperate from the back

slim ferry
#

just add a soul_pos parameter in the joker that points to the floating sprite location in the atlas

distant junco
#

alright

knotty orchid
clear ocean
#
poll_question_text

For the Memory Card joker, which memory card do you want me to recreate?

victor_answer_votes

3

total_votes

3

victor_answer_id

2

victor_answer_text

Dreamcast (Classic Gray, Jimbo as profile icon)

brittle yacht
#

how do i make a joker do something when a glass card is clicked

distant junco
#

idk if thats a checkable function icl

slim ferry
#

what actually is G.I.CARD? i see it a lot in the files, is it just all cards currently in play?

unkempt thicket
#

How do i make a joker animated?

knotty orchid
sturdy compass
#

Do discovery bypasses just not take the card name into account???

distant junco
wispy falcon
#

How do I change the sprite of a Joker mid-game?

sturdy compass
#

Still nope

rocky plaza
rocky plaza
#

at the bottom of the screenshot

#

is called every frame

wispy falcon
#

And can I put requirements there? Like if I want it to change after activating, for example

brittle yacht
dreamy thunder
#

there is this

slim ferry
# brittle yacht bump

you should be able to do something with the function that highlights/unhighlights cards when you click on them. id imagine you have to do fancy hook stuff and then make a context for it in SMODS.calculate_context

frosty rampart
#

yea that's not even super fancy, all you'd do in the hook is calculate the custom context and then pass it off to the old version of the function

dreamy thunder
#

^

wispy falcon
#

Does someone have a guide or video that explains the update function?

dreamy thunder
frosty rampart
#

it's literally just a function that runs every frame

dreamy thunder
#

thats the only thing about it

frosty rampart
#

you can do whatever you want in it, it's just a quick way to have something happen if you need to be checking the condition constantly

wispy falcon
#

Ohhh, okay. Thank you :3

#

And what do I need to write in it to change sprites?

frosty rampart
#

that set_sprite_pos function you were asking about earlier will change the sprite

wispy falcon
#

How?

frosty rampart
#

you put in the { x = [something], y = [something] }, and it changes the card's sprite to whatever that position is in its atlas

split saddle
#

i'm having trouble making jokers retrigger :(

wispy falcon
split saddle
#

getting error "Found effect table with no assigned repetitions during repetition check"
I understand what it means, but I don't know what am I doing wrong

sturdy compass
frosty rampart
brittle yacht
#

if a glass card is selected/clicked, it game overs you

wispy falcon
slim ferry
brittle yacht
slim ferry
#

okay simple explanation

frosty rampart
wispy falcon
frosty rampart
#

show me your joker code

slim ferry
# brittle yacht i havent worked with hooks before

basically what you do is you make a copy of the function that you want to hook in another variable,
then, you can edit the function you want to hook as long as you call the original function within it (youre basically just adding code into the original function)
for example this hook that i made once:

brittle yacht
#

what

slim ferry
#

first line is copying SMODS.poll_enhancement (the original one)

#

and then everything after is just

wispy falcon
# frosty rampart show me your joker code
    key = "final_push",
    path = "j_SPACEHOLDER.png",
    px = 71,
    py = 95
})

SMODS.Joker{
    key = "final_push",
    config = { extra = { xchips = 2 } },
    pos = { x = 0, y = 0 },
    rarity = 3,
    cost = 8,
    blueprint_compat = true,
    eternal_compat = true,
    unlocked = true,
    discovered = true,
    effect = nil,
    atlas = 'final_push',
    soul_pos = nil,

    calculate = function(self, card, context)
        if context.joker_main and G.GAME.current_round.hands_left == 0 then
            return {
                xchips = card.ability.extra.xchips
            }
        end
    end,

    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.xchips }, key = self.key }
    end,
}```
slim ferry
#

where eventually the old function gets called

#

so the original stuff still happens

#

here im using it to modify the arguments that get put into the function

frosty rampart
slim ferry
#

but you can do basically anything

brittle yacht
#

im so confuzzled 😭🙏

slim ferry
#

uhhhhh,,,,,,,,,,,,,,,,,,,,,

brittle yacht
#

im sorry 😭

slim ferry
#

idk im not a hook expert lmao

#

im definitely not the best at explaining this

brittle yacht
#

D:

slim ferry
#

but ill just give an example see if that helps

bold sleet
#

Hey, does anyone happen to know how to make a custom voucher that does the same shit as tarot/planet merchant/tycoon?

#

I checked the source code and it seems it is reading from a hardcoded table I cannot modify.

#

(because it is locally stored in the function)

wispy falcon
slim ferry
# brittle yacht D:
examplefunction_old = examplefunction
function examplefunction(argument1, argument2) --example hook!
    --everything you want to do BEFORE the original function goes here
    local ret = examplefunction_old(argument1, argument2)
    --everything you want to do AFTER the original function goes here
    return ret
end

does this help at all?

frosty rampart
brittle yacht
#

nah i reworked it ur good

#

its fine

slim ferry
#

okay

wispy falcon
frosty rampart
#

no. but you shouldn't need to, because you can just pick a different part of the image to display

#

the game is designed for an atlas to contain a bunch of sprites in one image

wispy falcon
#

So I could make a bigger image (with both images in it) and just position it differently?

frosty rampart
#

yes. that is exactly what i've been saying

ivory citrus
#

Helo

wispy falcon
ivory citrus
#

Does anyone know how to port my mod to mobile?

frosty rampart
#

modding rule 4

ivory citrus
frosty rampart
ivory citrus
knotty orchid
#

Is there any way to change the tooltip on uiboxes?

      n = G.UIT.C,
                    config = {
                        align = "cm",
                        colour = { 0.3, 0.3, 0.3, 0.5 },
                        r = 0.1,
                        minw = 2,
                        padding = 0.05,
                        outline = 1,
                        outline_colour = G.C.BLACK,
                        hover = true,
                        tooltip = { title = "Barriers" }
                    },```
wet crag
#

what do i need to do to have an effect activate on the first scoring card of the first hand of the round if the hand matches a rotating hand type variable (as with to-do list)?
im trying to use

if context.cardarea == G.jokers and context.joker_main then
            if context.scoring_name == G.GAME.current_round.pokervar_hand and (G.GAME.current_round.hands_played == 0) and context.other_card == context.scoring_hand[1] then

as well as :

if context.cardarea == G.jokers and context.joker_main then
  if context.scoring_name == G.GAME.current_round.pokervar_hand then
    if (G.GAME.current_round.hands_played == 0) then
      if context.other_card == context.scoring_hand[1] then

but it isnt working

frosty rampart
#

context.other_card doesn't exist in context.joker_main,
but you don't need that check at all, you can just use context.scoring_hand[1] directly

wet crag
#

oh shoot

slim ferry
#

is there a table that contains all the rarities?

wispy falcon
#

Another quick question regarding card.children.center:set_sprite_pos({x = x, y = y}) How do I know what x and y?

slim ferry
#

look at your atlas image

#

the top-left sprite in it is x = 0, y = 0

#

from there its just a grid of coordinates

wispy falcon
#

So I just take a guess till I get it right?

slim ferry
#

you can look at the spritesheet for the coordinates

#

down 1 sprite is +1 y and right 1 sprite is +1 x

wispy falcon
#

What spritesheet?

frosty rampart
#

the image that contains the sprites

#

whatever image you set the atlas to

wispy falcon
#

Oh, I'm stupid... I didn't know it's called that

wind steppe
wispy falcon
#

I meant that it's called a sprite sheet

ivory widget
#

How would a joker destroy the cards between the cards selected for Hanged Man?

split saddle
#

is there a context for creating consumables?

wind steppe
split saddle
#

obtaining in every form except buying

#

but I guess i can exclude buying from shop and it'd be the same

wind steppe
#

hm. no idea

#

you could hook create_card maybe?

split saddle
#

what is the cardarea for consumables

#

i think i can use card_added maybe

wind steppe
#

not misspelled

split saddle
split saddle
#

but I think I can work with that

frosty rampart
wild escarp
#

How could I track and level up unplayed hands each round?

wispy falcon
#

I feel stupid asking this but why is my joker getting invisible when I set the sprite pos to something other than x = 0, y = 0?

frosty rampart
# wild escarp How could I track and level up unplayed hands each round?

the documentation may not be perfect, but in this case you can see that context.before gets the name of the scoring hand in context.scoring_hand. https://github.com/Steamodded/smods/wiki/Calculate-Functions
so you can track the scored hands in a subtable in card.ability.extra, then iterate through SMODS.PokerHands at the end of the round and level up all the hands that you didn't track. and then reset the table of scored hands afterwards so that the next round starts fresh

frosty rampart
split saddle
#

how do you do card.type = consumeable?

#

like, the correct way to do it in code

agile path
#

good evening chat

wispy falcon
frosty rampart
#

sprite pos isn't the pixel position, it's the sprite position. you should set it to (x = 1, y = 0)

wispy falcon
#

But how does it know what of it a sprite is?

errant talon
#

Hello, there is no example regarding the use of assert
calculate = function(self, card, context) if context.cardarea == G.scored then if context.other_card:get_id() == 13 or context.other_card:get_id() == 11 then message = 'Queen!' and assert(SMODS.change_base(played_card, "12"))

Whenever i try to get this joker to work, i get either error of context other_card being not recognised, or error about change_base lacking cards

errant talon
frosty rampart
agile path
errant talon
#

assert should function like strenght in this regard

agile path
#

yoooo, i'm trying to do that

#

queens into kings and kings into queens

split saddle
#

How do you change the edition of a card?

split saddle
#

specifically, a consumable

wet crag
#

my mod has jestosterone which does the opposite lmao

daring fern
frosty rampart
#

^ your issue wasn't the assert, but the context checks beforehand

frosty rampart
wet crag
#

great minds think alike

agile path
#

hehehe

errant talon
#

what is the fix to that for the future?

daring fern
frosty rampart
daring fern
#

And it was doing that every time a context was called.

wintry solar
#

It shouldn’t ever have reached that line though if the copied code is correct

chrome widget
errant talon
split saddle
modern kindle
worthy stirrup
#

can i borrow one

agile path
frosty rampart
#

the brackets aren't actual code, it's showing what other context values will be set to if context.skip_blind is true. in that case you don't really get much of anything, you just get to know that you're currently skipping a blind

slim ferry
#

inside the brackets is just the additional information that exists in the context

#

yeha that

agile path
#

ah, so if i do an if context.skip_blind, that cardarea and skip_blind activate by default?

wind steppe
split saddle
#

now I want to know how to set the edition

wind steppe
split saddle
#

apparently you use card:set_edition but it's not working for me

wind steppe
split saddle
split saddle
#

when acquired and not bought

split saddle
errant talon
wind steppe
buoyant thorn
#

how do i make a deck that starts with a joker that has a custom edition?

daring fern
buoyant thorn
#

also hi wow cute ralsei pfp

wind steppe
split saddle
#

you need to pass a table and i wasn't doing that

buoyant thorn
wind steppe
#

apply contains everything you need

errant talon
daring fern
errant talon
errant talon
void sparrow
#

anyone knows why my messages don't trigger but the event does?

errant talon
agile path
daring fern
errant talon
#

that what @daring fern , it just, they updated the code in previous comment and edited it so i did not notice it

errant talon
#

before it is scored

agile path
#
        if context.individual and context.cardarea == G.play  then
            if context.other_card:get_id() == 12 then
                assert(SMODS.change_base(context.other_card, nil, "King"))
                return {
                    message = "Card Modified!"
                }
            end
        end
    end

would this work?

wind steppe
errant talon
agile path
#

i don't remember who showed me this today, but i have been looking into it

wet crag
#

what am i doing wrong here? probably a lot. but im trying to make it so that if the first hand scored coincides with a randomly selected hand (as per to-do list), the first scored card modifies the poker hand's base chips and mult based on its scoring values. the joker seems to activate but the hand's values don't actually change

calculate = function(self, card, context)
        if context.scoring_name == G.GAME.current_round.pokervar_hand then
            if context.individual and context.cardarea == G.play then
                if (G.GAME.current_round.hands_played == 0) then
                    if context.other_card == context.scoring_hand[1] then
                        context.other_card.should_destroy = true
                        local chips = card_chips
                        local mult = card_mult
                        local x_mult = card_xmult or 0
                        local text = G.FUNCS.get_poker_hand_info(G.play.cards)
                        G.E_MANAGER:add_event(Event({
                            func = function()
                                G.GAME.hands[text].chips = G.GAME.hands[text].chips + chips
                                G.GAME.hands[text].mult = G.GAME.hands[text].mult + mult
                                if x_mult > 0 then
                                    G.GAME.hands[text].mult = G.GAME.hands[text].mult * x_mult
                                end
                                return true
                           end
                        }))
                        return {
                            message = "AUGMENT!"
                        }
                        end
                    end
                end
            end
wind steppe
#

jokerforge is limited

agile path
wet crag
#

what do you mean?

agile path
#

i feel like it's still a great tool, specifically for me lol

frosty rampart
agile path
#

oh, another iris

#

hi iris

#

i'm iris 2

void sparrow
#

hi kimi or iris 2

daring fern
#

Also move the event out of the return.

modern kindle
#

Hi smt

daring fern
agile path
ivory widget
void sparrow
daring fern
#

And you would remove the } below the r in return and you would remove the };

void sparrow
#

okay thank oyu!!

wet crag
#

i could just take the raw value of the score after the card is played but that won't properly multiply the base values when xMult is involved

ivory widget
# daring fern Yes.

I think I understand taking ownership, but still don't understand how to detect the cards between the selected ones

frosty rampart
#

gimme a second to find the exact syntax

wet crag
#

thank you, and sorry for asking so many questions! :D

daring fern
daring fern
frosty rampart
#

yes that's it

wet crag
#

i cry everytime

#

it seems that get_chip_bonus() and get_chip_mult() exist, but not for the xmult and xchips. so I may need to make those myself

frosty rampart
#

it's get_chip_x_mult() lmao

#

and it should be get_chip_x_bonus() for the xchips one

ivory widget
daring fern
void sparrow
#

is there a scaling method for messages?

split saddle
#

this is what i've been up to (for the ppl that helped me (thanks guys))

I want to turn every consumable that is obtained through other than shopping to be turned negative. Right now, all consumables, regardless of origin, are converted. I would do something with buying_card, but it's called after card_added; I implemented a hack in the meantime.
There must be a way to do this in a more organized manner, but idk how to. Someone suggested doing a hook, but that's a little bit above what I can do (last time I tried to do something similar, I spent an hour to fruitless results). Any better ideas?

wet crag
# frosty rampart and it should be `get_chip_x_bonus()` for the xchips one

this works perfectly!! thank you so much!
one last thing, if you know; this works for the card itself and its enhancements but it isnt adding any bonuses from the card's edition. i tried to use context.other_card.edition:get_chip_bonus() etc. but that didn't work, likewise with using context.scoring_hand[1]:get_chip_bonus()

ebon shell
#

i copied the code to juice up the joker from invisible joker, so why is it visibly different from invisible joker's juice up animation?

daring fern
red flower
proven belfry
#

what's the size for mod icons in the mod menu

wet crag
#

you have all genuinely been so incredibly helpful i can't thank you enough. i apologize for the very frequent questions but sincerely appreciate the assistance!!

ebon shell
formal quest
#

How possible is it for me to make contained hands count as played hands? It seems like the "played" hand is controlled by context.scoring_name, is there anything I can do with that?

#

I've already implemented contained hands adding score, that's just some manual addition

red flower
#

seems very hard

#

at least if you plan to support mods

knotty orchid
#

What is the function that loads a game?

#

Like the one to continue an started game

formal quest
#

Definitely not worth rewriting a bunch of stuff for one joker

red flower
charred widget
#

Hello friends! I have a problem with one of my jokers

#

This is Ho-oh, and it's mechanic is that whenever three cards are discarded, it destroys them and replaces them with three randomly enhanced face cards.

#

But today while I was playing with it, I noticed that it only destroys the first card, not all three cards

knotty orchid
#

is there any reason this doesn't work when loading a game but it works perfectly if you start a new run?

[patches.pattern]
target = 'functions/state_events.lua'
pattern = "delay(0.4); ease_ante(1); delay(0.4); check_for_unlock({type = 'ante_up', ante = G.GAME.round_resets.ante + 1})"
position = 'at'
match_indent = true
override = true
payload = '''
if not G.GAME.blind.small and not G.GAME.blind.big then
    delay(0.4)
    ease_ante(1)
    delay(0.4)
    check_for_unlock({type = 'ante_up', ante = G.GAME.round_resets.ante + 1})
end```
#

I've defined two new properties for blinds, small and big

#

so I can create custom small and big blinds

slim ferry
charred widget
slim ferry
#

just remove and card.ability.extra.added from the context.discard check

#

and just add another check for discarding exactly three cards instead

#

also use SMODS.add_card instead of that entire thing you have to add a face card

#

oh wait

#

no youre using SMODS.add_card() like create_card(), you can just do SMODS.add_card on its own and itll add the card to the area it should be in

#

also dont know if its intentional, but currently its making specifically a jack, queen and king

charred widget
#

I knew it was doing that but I haven't bothered anyone to make the ranks random yet

slim ferry
#

also i'd imagine its easier to just convert the cards directly instead of adding and destroying but i would have to look up how to do that

charred widget
#

yeah you're probably right

void sparrow
#

i'm trying to make a joker that copies the joker to its right but has a 1/4 chance to destroy it
my issue is that its never copying it

slim ferry
#

first issue is old probability system

#

well not an issue but you should switch to the new one

void sparrow
slim ferry
#

it shouldnt need a context check at all

#

vanillaremade blueprint is just this

void sparrow
#

so just, directly after calculate

slim ferry
#

it is still in the calculate, just without any context check

void sparrow
#

aaaaaaaah, i'll try

slim ferry
#

oh wait

#

nvm im blind lMAO

#

you shouldnt need any arguments for start_dissolve though i think

void sparrow
#

game crashed

slim ferry
#

uh probably the random closing curly bracket?

#

unless thats closing something i cant see

void sparrow
#

-50IQ, i closed the joker

slim ferry
#

😭

#

wonderful

knotty orchid
#

When you go to the main_menu from a run, what is the function that stores the info from that run?

knotty orchid
#

It seems so yea

void sparrow
slim ferry
#

i assume now you arent closing the joker at all

#

which is pretty important

frosty rampart
#

you're ending the whole calculate function after the first blueprint_effect, adding the whole check_for_unlock function, and then continuing to write more code that i assume wants to be in the calculate function

void sparrow
#

it just want to close it here

slim ferry
#

oh yeah why is check_for_unlock in the calculate

#

that should be its own thing

#

if you even want it

frosty rampart
#

check_for_unlock isn't in the calculate

#

the calculate ends right before it

#

and then there's more calculate code outside of any function

slim ferry
#

oh yeah

#

the calc ends early

#

also please right click and do format document this indentation isnt great

void sparrow
#

ok hold on, im trying to format bc its not in my right click menu

slim ferry
#

if you right click anywhere on the document it should have a format document option

#

and if not you can just select everything and do format selection instead

wet crag
#

hi all. back again because i break everything constantly lmao.
this works when the card has an edition, but when it doesnt, i get an error stating that im trying to index edition which is nil. so the "or 0" and "or 1" don't kick in and the game crashes when i attempt to score an uneditioned card with the joker

calculate = function(self, card, context)
        if context.scoring_name == G.GAME.current_round.pokervar_hand then
            if context.individual and context.cardarea == G.play then
                if (G.GAME.current_round.hands_played == 0) then
                    if context.other_card == context.scoring_hand[1] then
                        context.other_card.should_destroy = true
                        local chips = context.other_card:get_chip_bonus()
                        local edition_chips = context.other_card.edition.chips or 0
                        local mult = context.other_card:get_chip_mult()
                        local edition_mult = context.other_card.edition.mult or 0
                        local x_mult = context.other_card:get_chip_x_mult() or 1
                        local edition_x_mult = context.other_card.edition.x_mult or 1
                        local x_chips = context.other_card:get_chip_x_bonus() or 1
                        local edition_x_chips = context.other_card.edition.x_chips or 1
                        local e_mult = context.other_card:get_chip_e_mult() or 1
                        local edition_e_mult = context.other_card.edition.e_mult or 1
                        local e_chips = context.other_card:get_chip_e_bonus() or 1
                        local edition_e_chips = context.other_card.edition.e_chips or 1
                        local text = G.FUNCS.get_poker_hand_info(G.play.cards)
                        ...
void sparrow
#

formating did nothing, the code didn't change lmao

slim ferry
slim ferry
#

makes it better readable

wet crag
frosty rampart
#

you can just say "if context.other_card.edition", nil is treated as false and nearly anything else as true

daring fern
void sparrow
slim ferry
#

well doesnt really matter

#

this code looks like it should work though

void sparrow
#

it refused, my IQ is lowering after each crash

frosty rampart
#

you're always returning no matter what at the blueprint effect, so i think the game doesn't like that you have more code after it

void sparrow
#

but if i add an end it closes the calculate

slim ferry
#

just put the blueprint effect after probably

#

that should work just fine

void sparrow
#

blueprint doesn't wrk,,,

wet crag
#

placeholder art but it finally works as intended !!!

wild escarp
#

I've got this to add all played poker hands to a table, so how can I cycle through and upgrade all poker hands not in the table?

if context.before and context.main_eval and not context.blueprint then
    card.ability.extra.scored_hands[#card.ability.extra.scored_hands+1] = context.scoring_hand
end
clear ocean
subtle merlin
#

how can i tell how many cards are being destroyed in context.destroy_cards (or context.destroying_cards if that's the right context)?

red flower
#

destroy_card is to destroy, remove_playing_cards is when they're destroyed

#

#context.removed would be the number

split saddle
#

left is scoring, right is unscoring

subtle merlin
red flower
#

yes

#

i think

wet crag
subtle merlin
unborn bay
split saddle
#

I did a fix already, but thanks

unborn bay
#

ah good

split saddle
#

instead of doing v:set_edition() inside of the event, i just v:juice_up() and it worked out fine

ivory widget
# daring fern ```lua for k, v in pairs(G.hand.highlighted) do local my_pos for i=1, #G...

apologies for the late reply, got caught up in something
how do i use the my_pos from here? this is what i made so far, but it doesn't work

for k, v in pairs(G.hand.highlighted) do
          local my_pos
          for i=1, #G.hand.cards do
            if G.hand.cards[i] == v then
                my_pos = i
            end
          end
        end
        for i=1, #G.hand.cards do
          if G.hand.cards[i] <= my_pos then
            G.hand.cards.to_be_removed_by = card
          end
        end
wind steppe
#

how do i get a poker hand's name from its key?

mild night
#

can someone explain to me what 'G.SHADERS['CRT']:send('noise_fac',0.001*G.SETTINGS.GRAPHICS.crt/100)' does exactly in game.lua

short girder
#

this dude is iterating through every card in the deck for count for some reason, which i dont want it to do

config = { extra = { count = 0 }},
...
--in the calculate function
  if context.end_of_round and not context.repetition and context.individual then
    card.ability.extra.count = card.ability.extra.count + 1
  end
normal crest
wind steppe
#

it applies the crt effect based on your settings

short girder
#

i want it to happen after idk 3 rounds lets say

#

however since it iterates over all the 52 cards in the deck the goal is met instantly

normal crest
normal crest
short girder
#

gotcha

cursive gazelle
#

@chrome widget , hey . do you have any idea how can i replace / draw on top of the existing background shader ?

jolly summit
wind steppe
#
    local _hand, _tally = "Straight Flush", to_big(-1) -- ty vanillaremade for giving me all this code
    for _, handname in ipairs(G.handlist) do
        if SMODS.is_poker_hand_visible(_hand) and to_big(G.GAME.hands[handname].played) > to_big(_tally) then
            _hand = handname
            _tally = to_big(G.GAME.hands[handname].played)
        end
    end
``` why does this crash with custom poker hands (aikoshen)
chrome widget
short girder
subtle merlin
#

I don't understand why this is crashing, by my understanding it should make a playing card with a random suit, rank and have the chance at a random enhancement

jolly summit
normal crest
#

update to 0711a

normal crest
subtle merlin
jolly summit
#

yup with joker forge

normal crest
jolly summit
#

ok ty

normal crest
wind steppe
#

this one was from a slightly older version that passed the localized name into SMODS.is_poker_hand_visible

#

they both crash though

normal crest
#

send the latest crash

#

not an old one

red flower
#

why would is_poker_hand_visible not take the localized name who designed this

wind steppe
#

it just decided to randomly fix itself never mind

normal crest
#

glad to hear

wind steppe
#

most balanced cryptid joker

normal crest
subtle merlin
normal crest
vast night
#

hey quick question: how do i use pseudorandom_probability? I've used the exact same setup as all my other jokers but for some reason im either really lucky hitting literally a 1 in 625 or somethings wrong.

SMODS.pseudorandom_probability(card, 'j_mod_myjoker', card.ability.extra.chance_min, card.ability.extra.chance_max) (chance_min and max are defined and showing up in loc_vars)

daring fern
tiny hemlock
#

hello, anyone knows how to play music like when the custom joker is (on the jokers area) and enterin a round the music / theme plays and when the round ends it stops?

keen sleet
#

Should I let the mult be a decimal or round it to be more vanilla?

rocky plaza
#

or down, do whatever

keen sleet
#

Rounding up is a good idea

true sky
#

is there a way to modify the cards in a booster pack after they're already generated? like, adding a specific seal to all the cards that didn't already have a seal, for instance

red flower
#

if anyone finds this info useful

#

i will add it to the vremade wiki later

subtle merlin
red flower
#

it picks a tarot or planet

subtle merlin
#

oh, that makes sense

red flower
#

i will add a note

gusty compass
#

would anyone happen to know if removing cards can work when a hand is played?

short girder
#

how do i fetch a joker name from a key?

short girder
#

gotcha

gusty compass
#

yea

#

do you need the code by any chance?

red flower
#

you can destroy the card in context.press_play

short girder
red flower
short girder
#

gotcha

gusty compass
#

so context.press_play might be interfering with next(context.poker_hands["Three of a Kind"])

red flower
#

yeah poker hands are not calculated until after

#

what's the intended effect?

gusty compass
#

when you play a three of a kind, with the first card (scoring or not) being a 7

#

gain $7 and destroy that card

red flower
#

oh, so you dont need the card to be destroyed before scoring then?

gusty compass
#

i suppose

red flower
#

use context.destroy_card and return { remove = true }

gusty compass
#

maybe after the money is given but im not sure if that works

#

i tried

red flower
#

and?

gusty compass
#

earlier a few times and it did nothing as far as i remember

red flower
#

show me the code then

gusty compass
#

only worked with context.discard

#

fyi i did make a few changes before i did the context.destroy_card thing

#

idk if it made a difference

#

calculate = function(self, card, context)
local condition = false

    if context.before and next(context.poker_hands["Three of a Kind"]) then
        for i = 1, #G.play.cards do
            if i == 1 and G.play.cards[i].base.id == 7 then
                condition = true
            end
        end

        if condition then
            ease_dollars(7)

            return {
                message = localize("$").."7",
                colour = G.C.MONEY,
                remove = true
            }
        end
    end
end
red flower
#

let me write how it would be for you

gusty compass
#

alr

red flower
#
calculate = function(self, card, context)
    if context.destroy_card and next(context.poker_hands["Three of a Kind"])
    and context.destroy_card == context.full_hand[1] and context.destroy_card:get_id() == 7 then
        return {
            dollars = 7,
            remove = true
        }
    end
end,
gusty compass
#

should i paste that in and see what happens with it?

red flower
#

yes

gusty compass
#

i dont think it did anything

red flower
#

how did you test it

#

and whats the current code looking like

gusty compass
#

SMODS.Joker {
key = "GG_777",
atlas = "atlasholders",
pos = {x = 1, y = 0},

rarity = 2,
cost = 7,

loc_txt = {
    name = "777",
    text = {
        "If the played hand is a {C:attention}Three Of A Kind{},",
        "and the first card is a {C:attention}7{} {C:inactive}(Scored or not){},",
        "destroy that card and gain {C:money}$7{}."
    }
},

calculate = function(self, card, context)
    if context.destroy_card and context.cardarea == G.play and next(context.poker_hands["Three of a Kind"])
    and context.destroy_card == context.full_hand[1] and context.destroy_card:get_id() == 7 then
        return {
            dollars = 7,
            remove = true
        }
    end
end,

--[[calculate = function(self, card, context)
    if context.before and next(context.poker_hands["Three of a Kind"]) then
        for i = 1, #G.play.cards do
            if i == 1 and G.play.cards[i].base.id == 7 then
                ease_dollars(7)

                return {
                    message = localize("$").."7",
                    colour = G.C.MONEY,
                    remove = true
                }
            end
        end
    end
end]]

}

#

i commented out my old one and used your one instead

red flower
#

oh oops i see the problem haha

gusty compass
#

its alright

red flower
#

there, edited it

#

it wasnt working with unscored cards

gusty compass
#

it works which is a plus

#

just curious if i can move it before scoring?

#

like when it happens

red flower
#

yeah but its a bit more complicated because you need to evaluate the poker hand manually, also it will change the poker hand so it might be a bit punishing (if a flush with a 3oak is played and the 7 is destroyed it wont count as a flush anymore)

gusty compass
#

oh, well i guess you win some and you lose some

#

thanks for the help though

subtle merlin
#

I understand some parts of patching now, but how can I find the target and pattern I want to patch?

red flower
#

the target is the line(s) in the code you want to patch before/at/after and the pattern is what you want to add to/replace it for

subtle merlin
#

Aahhhh, oki

ivory citrus
#

Hello, I am trying to make it so that for each blind selected, this moss card creates another moss card.

subtle merlin
lament agate
#

is there a way to affect the joker's scaling

#

looking at the scalae code, brain hurt

manic rune
#

hook to Game:update, check for value changes and multiply the difference

#

thats how i did it for stacked

lament agate
manic rune
#

mhm

lament agate
#

got it

#

thanks bepis

#

mwah

manic rune
#

:3

lament agate
manic rune
#

like, 99182 crashes specifically?

lament agate
#

mhm

manic rune
#

fire

#

check stacked's code in hooks.lua if u cant figure it out :3

red flower
#

hi bepis

manic rune
#

hi N'

#

how its going

red flower
#

im tired

#

going to zzzzzzz

manic rune
#

ic

red flower
#

just did 3 smods prs tho

manic rune
#

go to sleep then!

#

common W's W

lament agate
#

im used to hooking

#

i love hookers

manic rune
#

im giving you the silent treatment nxkoo

manic rune
#

wish i could help but im away from my pc for a few days sob

#

sorry

frigid cargo
#

bump

lament agate
oak meadow
#

how do i get a random number, being 1 or 2
im trying to look at the info thing for math.random() but its confusing

faint yacht
#

pseudorandom(pseudoseed('farts'), 1, 2)

oak meadow
#

best seed

plain ember
#

Hello guys, im really losing it with this, idk why is stack overflowing, and its not the getjokerid, its the "if G.jokers" line, can someone illuminate me please?

plain ember
#

Error screen if it helps

plain ember
#
function getJokerID(card) --Stolen from Yahiamice Mod
    if G.jokers then
        local _selfid = 0
        for i = 1, #G.jokers.cards do
            if G.jokers.cards[i] == card then _selfid = i end
        end
        return _selfid
    end
end
manic rune
#

mm

#

dont save cards into your card.ability

#

its a bad idea

plain ember
#

I'm very new at modding balatro, so im just making a bunch of random stuff to learn how does the enviroment work

#

Should i store it in locals then?

manic rune
#

nop

#

mark the joker with a flag

#

whats the effect

plain ember
#

Its supposed to force trigger a joker from its sides

manic rune
#

why do you need to store jokers then?

plain ember
#

Force trigger

#

not like, retriggering

manic rune
#

does force trigger need to do that

plain ember
#

but now that you say it

manic rune
#

that sounds weird

oak meadow
#

can you not just get the placement of the joker and toss that in there

manic rune
#

-# for context, ive never checked how cryptid's force trigger works

sturdy compass
oak meadow
#

itd make sense

plain ember
sturdy compass
#

I have broken that thrice now lmfao

manic rune
plain ember
#

I could save the placement instead of the card itself

manic rune
#

:3

#

you also dont need to save the placement

#

how are jokers force triggered?

plain ember
#

According to cryptid, just card and context as args

oak meadow
#

pretty sure you could just replace card with the location

manic rune
#

mhm

oak meadow
#

or use that as i mean

plain ember
#

I dont want to touch the og cryptid code, so ill just store the number placement and call it with G.jokers.cards[id]

#

instead of saving it

manic rune
#

does Cryptid.forcetrigger return a table?

oak meadow
#

no like
dont touch the cryptid code

#

just use the location of the card as card

manic rune
#

if so, you want to use SMODS.merge_effects too

plain ember
#

what's merge effects?

manic rune
#
local id = getJokerID(card)
if id then
   local ret1 = G.jokers and G.jokers.cards[id+1] and Cryptid.forcetrigger(G.jokers.cards[id+1], context) or {}
   local ret2 =  G.jokers and G.jokers.cards[id-1] and Cryptid.forcetrigger(G.jokers.cards[id-1], context) or {}
   return SMODS.merge_effects({ret1, ret2})
end
#

either that or

just Cryptid.force_trigger on the adjacent jokers without returning anything

#

idk

lament agate
#

@manic rune this is just for you

manic rune
#

good job nxkoo

lament agate
#

ghh

manic rune
manic rune
plain ember
#

I think imma test it tomorrow, its quite late here, i'll do some tests with it tho

manic rune
#

mhm

#

do note this is assuming that it works like SMODS.blueprint_effect

oak meadow
#

if i do G.money = G.money - 5
will it just do what i think
because i dont remember if thats how that works it probably is but i feel like i have to ask sry

manic rune
#

ease_dollars(-5)

plain ember
manic rune
#

and its G.GAME.dollars for the value

#

-# changing it directly wont give you the animation

oak meadow
#

ty

wild escarp
#

Is there an example of a modded joker that upgrades multiple hands at once somewhere?

plain ember
#

Think it like
a card that forces a perkeo at its side without fulfilling its context requirements

oak meadow
#

i can call ease_dollars() outside of a return riht

manic rune
#

mhm

oak meadow
#

ok just making sure

plain ember
oak meadow
#

how do i get a random poker hand