Examples - larswijn/CardSleeves GitHub Wiki

Examples

This page will have some examples of Sleeves and how to use them in other mods. You can also check out the source code to see how the 15 base sleeves are implemented, or other mods that have implemented Sleeves, such as SDM_0's implementation.

Reminder to use

if CardSleeves then
    -- sleeve code
end

The most basic Sleeve

A Sleeve with no effects.

CardSleeves.Sleeve {
    key = "example",
    atlas = "sleeve_atlas",  -- you will need to create an atlas yourself
    pos = { x = 0, y = 0 },
    loc_txt = {
        name = "Example Sleeve",
        text = { "Does nothing" }
    }
}

A Sleeve that uses CardSleeve's default atlas

If you'd like to use CardSleeve's default sprites as placeholders, add prefix_config = {atlas=false} and point the atlas to "casl_sleeve_atlas".

CardSleeves.Sleeve {
    prefix_config = {atlas=false},
    atlas = "casl_sleeve_atlas",
    pos = { x = 1, y = 3 },
    ...
}

A Sleeve with localization in a separate file

Assuming the mod name is test:

In test.lua

CardSleeves.Sleeve {
    key = "example",
    ...
}

In localization/default.lua or localization/en-us.lua

return {
    descriptions = {
        Sleeve = {
            sleeve_test_example = {  -- "sleeve_" + mod prefix + "_" + sleeve original key
                name = "Example Sleeve",
                text = { "Does nothing" }
            }
        }
    }
}

A Sleeve with actual effects

This sleeve actually has an effect and description.

CardSleeves.Sleeve {
    key = "example",
    atlas = "sleeve_atlas",
    pos = { x = 1, y = 0 },
    config = { hands = 1 },
    loc_txt = {
        name = "Example Sleeve",
        text = { "{C:blue}+#1#{} hand", "every round" }
    },
    loc_vars = function(self)
        return { vars = { self.config.hands } }
    end,
}

A Sleeve that changes effect based on the deck

This Sleeve normally gives +1 hand, but when combined with the blue deck gives +2 discards instead.

This will require a separate localization file! Again assuming the mod name is test.

In test.lua

CardSleeves.Sleeve {
    key = "example",
    ...,
    loc_vars = function(self)
        local key, vars
        if self.get_current_deck_key() ~= "b_blue" then
            key = self.key
            self.config = { hands = 1 }
            vars = { self.config.hands }
        else
            key = self.key .. "_alt"
            self.config = { discards = 2 }
            vars = { self.config.discards }
        end
        return { key = key, vars = vars }
    end,
}

In localization/default.lua or localization/en-us.lua

return {
    descriptions = {
        Sleeve = {
            sleeve_test_example = {
                name = "Purple Sleeve",
                text = { "{C:blue}+#1#{} hand", "every round" }
            },
            sleeve_test_example_alt = {
                name = "Purple Sleeve",
                text = { "{C:red}+#1#{} discards", "every round" }
            },
        }
    }
}

A Sleeve with a custom apply()

If you create a Sleeve with a custom apply() method, the original no longer gets called, so call it if you need to.

CardSleeves.Sleeve {
    ...,
    config = { joker_slot = 2, win_ante = 10 },
    apply = function(self)
        -- base apply does not support setting the win_ante, so we have to do it ourselves
        G.GAME.win_ante = self.config.win_ante

        -- pick one of the 2 next options to change joker slots
        -- option A: call base apply to apply the +2 joker slots:
        CardSleeves.Sleeve.apply(self)
        -- option B: apply the +2 joker slots yourself
        G.GAME.starting_params.joker_slots = G.GAME.starting_params.joker_slots + self.config.joker_slot
    end
}

A Sleeve with a custom trigger_effect(args)

If you create a Sleeve with a custom trigger_effect(args) method, the original no longer gets called, so call it if you need to.

This Sleeve adds 10 chips and 1 mult as final scoring step.

CardSleeves.Sleeve {
    key = "example",
    ...,
    config = { chips_bonus = 10, mult_bonus = 1 },
    trigger_effect = function(self, args)
        CardSleeves.Sleeve.trigger_effect(self, args)  -- perform original trigger_effect (it does nothing in this case)
        
        if G.GAME.selected_sleeve == "sleeve_test_example" and args.context == "final_scoring_step" then
            -- G.GAME.selected_sleeve check isn't needed here, but might be useful in other instances

            args.chips = args.chips + self.config.chips_bonus
            args.mult = args.mult + self.config.mult_bonus

            update_hand_text({delay = 0}, {mult = args.mult, chips = args.chips})  -- visual only
            
            return args.chips, args.mult  -- make sure to return chips/mult if you want to actually modify the score!
        end
    end
}

A Sleeve that is locked

Sleeves can be locked (like any other center) so the player cannot use them until unlocked. Discovering Sleeves does not exist, and they are always "discovered" by default. Using unlock all or the in-game CardSleeves config option allows the player to bypass all unlock conditions.

Basic locked Sleeve

A basic locked Sleeve using unlock_condition. This Sleeve unlocks after beating the green deck on gold stake.

CardSleeves.Sleeve {
    ...,
    unlocked = false,
    unlock_condition = {deck = "b_green", stake = 8},
}

Custom locked Sleeve

A custom locked Sleeve by re-implementing check_for_unlock and locked_loc_vars. Make sure to define an entry in the localization.

CardSleeves.Sleeve {
    ...,
    unlocked = false,
    unlock_condition = { type = "ante_up", ante = 12 }
    check_for_unlock = function(self, args)
        -- see function check_for_unlock(args) at functions/common_events.lua:1163 in the base-game for more unlock types
        if args.type == self.unlock_condition.type and args.ante >= self.unlock_condition.ante then
            return true
        end
    end,
    locked_loc_vars = function(self, info_queue, card)
        -- very similar to loc_vars
        local key = "sleeve_locked_ante"  -- do not use `sleeve_locked`, already used by CardSleeves
        local vars = { self.unlock_condition.ante }
        return { key = key, vars = vars }  -- make sure localization has an entry for this key
    end
}

A Sleeve based on a deck

If a deck has an "independent" apply or trigger_effect, you might be able to simply reference it while creating the Sleeve for it instead of having to copy-paste the effect. Obviously does not work if you would like your sleeve to have a unique deck+sleeve effect. Assuming mod name is test.

SMODS.Back {
    key = "example",
    pos = {x = 0, y = 4},
    loc_txt = {
        name = "Example Deck",
        text = { "Adds loads of cards at every final scoring step" }
    },
    trigger_effect = function(self, args)
        if args.context == "final_scoring_step" then
            for k, v in pairs(G.P_CARDS) do
                local s, r = string.sub(k, 1, 1), string.sub(k, 3, 3)
                card_from_control({s=s, r=r})  -- add to deck function in base balatro
            end
        end
    end
}

CardSleeves.Sleeve {
    ...,
    -- The example deck's trigger_effect does not use config values or similar, and can just be referenced here
    trigger_effect = SMODS.Back.obj_table["b_test_example"].trigger_effect
}

Modify one of the base sleeves

In case you'd like to modify the effects of one of the default sleeves.

Changing the config of a simple sleeve

local red_sleeve = CardSleeves.Sleeve:get_obj("sleeve_casl_red")
red_sleeve.config.discards = 10

Changing the config of a complicated (unique deck+sleeve effect) sleeve

Some sleeves reset their own config constantly depending on the selected deck. You will need to hook into loc_vars to change this behavior. You might also need to change the description (modify the returned key and create a localization for it) depending on the amount of changes you make.

test.lua

local zodiac_sleeve = CardSleeves.Sleeve:get_obj("sleeve_casl_zodiac")

-- doesn't work!
zodiac_sleeve.config = { vouchers = {'v_tarot_merchant', 'v_planet_merchant', 'v_magic_trick' } }

-- we will need to hook loc_vars
local zodiac_sleeve_loc_vars_ref = zodiac_sleeve.loc_vars
zodiac_sleeve.loc_vars = function(self)
    if self.get_current_deck_key() ~= "b_zodiac" then
        self.config = { vouchers = {'v_tarot_merchant', 'v_planet_merchant', 'v_magic_trick' } }
        local key, vars = self.key, {}
        for _, voucher in pairs(self.config.vouchers) do
            vars[#vars+1] = localize{type = 'name_text', key = voucher, set = 'Voucher'}
        end
        return { key = key, vars = vars}
    else
        return zodiac_sleeve_loc_vars_ref(self)
    end
end