Skip to content
N edited this page Jul 23, 2024 · 23 revisions

JokerDisplay API Documentation

Getting Started

If you want to add support for another mod or edit how vanilla Jokers look, it's recommended that you first look at how Jokers are already defined in display_definitions.lua.

If you are adding support in your mod, first you want to check if the player has JokerDisplay installed and that the main JokerDisplay object is loaded.

In Steamodded 1.0 it can be done like this:

if SMODS.Mods["JokerDisplay"] and _G["JokerDisplay"] then
    -- Definition code
end

It's also recommended to write the definitions in a separate file so they don't take too much space in your code. This can be done with NFS.

if SMODS.Mods["JokerDisplay"] and _G["JokerDisplay"] then
    NFS.load(SMODS.current_mod.path .. "joker_display_definitions.lua")()
end

Then either inside the conditional or in a separate file you have to define your Joker under JokerDisplay.Definitions using the Joker's key.

local jd_def = JokerDisplay.Definitions -- You can assign it to a variable to use as shorthand

jd_def["j_prefix_key"] = {
    -- Definition
}

Here's an example of how Bloodstone is defined so you can look at the general structure:

jd_def["j_bloodstone"] = {
    text = {
        { ref_table = "card.joker_display_values", ref_value = "count" },
        { text = "x",                              scale = 0.35 },
        {
            border_nodes = {
                { text = "X" },
                { ref_table = "card.ability.extra", ref_value = "Xmult" }
            }
        }
    },
    reminder_text = {
        { text = "(" },
        { ref_table = "card.joker_display_values", ref_value = "localized_text", colour = lighten(G.C.SUITS["Hearts"], 0.35) },
        { text = ")" }
    },
    extra = {
        {
            { text = "(" },
            { ref_table = "card.joker_display_values",                              ref_value = "odds" },
            { text = " in " .. G.P_CENTERS["j_bloodstone"].config.extra.odds .. ")" },
        }
    },
    extra_config = { colour = G.C.GREEN, scale = 0.3 },
    calc_function = function(card)
        local count = 0
        local hand = next(G.play.cards) and G.play.cards or G.hand.highlighted
        local text, _, scoring_hand = JokerDisplay.evaluate_hand(hand)
        for k, v in pairs(scoring_hand) do
            if v:is_suit("Hearts") then
                count = count +
                    JokerDisplay.calculate_card_triggers(v, not (text == 'Unknown') and scoring_hand or nil)
            end
        end
        card.joker_display_values.count = count
        card.joker_display_values.odds = G.GAME and G.GAME.probabilities.normal or 1
        card.joker_display_values.localized_text = localize("Hearts", 'suits_plural')
    end
}

Definition Documentation

A definition is a table that can be composed of the following values (all of them optional)

text: (table) The main text of the Joker.

text_config: (table) Default configuration for text.

reminder_text: (table) Reminder text below the main text.

reminder_text_config: (table) Default configuration for reminder_text.

extra: (table) Extra text on top of the main text.

extra_config: (table) Default configuration for all extra rows.

calc_function: (function) This function gets called every time the display updates.

style_function: (function) This function is used to change attributes for the different text lines.

retrigger_function: (function) This function is used to calculate card retriggers caused by the Joker.

mod_function: (function) This function is used to add extra modifiers to other Jokers.

Text Objects

The fields text, reminder_text and extra are defined using text object tables. These objects will be displayed from left to right in that row, and you can combine any of them in any order.

Static Text

Static text is defined as follows:

{ text = "Text Here" }

You can change the colour and scale of it too.

{ 
    text = "Text Here", 
    colour = G.C.RED 
}
{
    text = "Text Here", 
    scale = 0.3 
}
{ 
    text = "Text Here", 
    colour = G.C.RED, 
    scale = 0.3 
}

Check the main Balatro code for color definitions.

For scale consistency use 0.4 for normal-sized text, 0.35 for smaller text and 0.3 for the smallest.

If you're using localization, don't use localize() in this field as it will always load the English translation independent of what the player has set. Use reference values instead.

Reference value

You can have the text change when some in-game valuable changes by pointing it at a table value.

{ 
    ref_table = "MyMod.important_values", 
    ref_value = "text_value"
}

ref_table is the table that holds ref_value.

card is a special ref_table keyword that looks for this Joker.

{ 
    ref_table = "card.ability.extra", 
    ref_value = "x_mult"
}

This mod also adds a table under card.joker_display_values you can use to save values for this mod when using calc_function.

{ 
    ref_table = "card.joker_display_values", 
    ref_value = "x_mult"
}

You can also change colour and scale.

{ 
    ref_table = "card.joker_display_values", 
    ref_value = "x_mult",
    colour = G.C.GREEN, 
    scale = 0.3 
}

Dynatext

You can use a Dynatext object by passing the configuration to dynatext.

{
    dynatext = {
        string = (
            function()
                local r_mult = {}
                for i = G.P_CENTERS["j_misprint"].config.extra.min, G.P_CENTERS["j_misprint"].config.extra.max do
                    r_mult[#r_mult + 1] = tostring(i)
                end
                return r_mult
            end
        )(),
        colours = { G.C.MULT },
        pop_in_rate = 9999999,
        silent = true,
        random_element = true,
        pop_delay = 0.5,
        scale = 0.4,
        min_cycle_time = 0
    }
}

Please check the main Balatro code for more information on Dynatext.

Border

You can create a border object using border_nodes to display X Mult or anything similar. Inside this table, you can use any of the previous definitions.

{
    border_nodes = {
        { text = "X" },
        { ref_table = "card.ability", ref_value = "x_mult" }
    }
}

By default the color of the border is G.C.XMULT, but you can specify another color by using border_colour.

{
    border_nodes = {
        { text = "X" },
        { ref_table = "card.ability", ref_value = "x_chips" }
    },
    border_colour = G.C.CHIPS
}

Field Specifications

text

This is the main text of the Joker. For consistency use this field for modifiers (chips, mult, Xmult, dollars) and keep any other values or text on other lines.

text =  {
    { 
        text = "+", 
        colour = G.C.CHIPS 
    },
    { 
        ref_table = "card.joker_display_values", 
        ref_value = "chips", 
        colour = G.C.CHIPS 
    }
}

The default colour for this row is G.C.UI.TEXT_LIGHT and the default scale is 0.4.

text_config

Use text_config to change the default colour and scale values for text.

text_config = {
    colour = G.C.MULT,
    scale = 0.35
}

For example, you can write the previous text code like this.

{
    text =  {
        { 
            text = "+"
        },
        { 
            ref_table = "card.joker_display_values", 
            ref_value = "chips"
        }
    },
    text_config = {
        colour = G.C.CHIPS
    }
}

reminder_text

Use this for any reminder text for the Joker's ability.

reminder_text = {
    { text = "(Every Round)" }
}

The default colour for this row is G.C.UI.TEXT_INACTIVE and the default scale is 0.3.

reminder_text_config

Same as text_config.

extra

Extra lines of text. These will be displayed from bottom to top. Vanilla definitions use this only for odds.

{
    extra =  {
        {
            { 
                text = "Extra Line 1"
            }
        },
        {
            { 
                text = "Extra ",
                colour = G.C.RED
            },
            { 
                text = "Line ",
                colour = G.C.GREEN
            },
            { 
                text = "2"
            }
        },
        {
            {
                border_nodes = {
                    { text = "Extra Line 3" },
                }
            }
        },
    }
}

The default colour for these rows is G.C.UI.TEXT_LIGHT and the default scale is 0.4.

extra_config

Same as text_config. Keep in mind that these values affect all rows in extra.

calc_function

This function gets called every time the display updates. Use this to calculate values that are not saved anywhere else or values that depend on the hand being played/highlighted.

Parameters:

card: (table) The Joker being calculated.

Returns:

Nothing.

-- Greedy/Lusty/Wrathful/Gluttonous Joker
-- Checks how many cards of a certain suit are in hand
calc_function = function(card)
    local mult = 0
    local hand = next(G.play.cards) and G.play.cards or G.hand.highlighted
    local text, _, scoring_hand = JokerDisplay.evaluate_hand(hand)
    for k, v in pairs(scoring_hand) do
        if v:is_suit(card.ability.extra.suit) then
            mult = mult +
                card.ability.extra.s_mult *
                JokerDisplay.calculate_card_triggers(v, not (text == 'Unknown') and scoring_hand or nil)
        end
    end
    card.joker_display_values.mult = mult
end

Plese check display_definitions.lua for more examples and Helper Functions section of JokerDisplay.lua for some useful functions.

style_function

This function is used to change attributes of the different text lines (mainly colour and style).

Parameters:

card: (table) The Joker being calculated.

text: (table) Main text object.

reminder_text: (table) Reminder text object.

extra: (table) Extra text object.

Returns:

recalculate: (boolean) If the display alignments should be recalculated. (Set to true if you're changing scale)

-- Sixth Sense
-- Changes text colour if it's active.
style_function = function(card, text, reminder_text, extra)
    if text and text.children[1] then 
    -- Make sure to check if the children exists or it will crash
        text.children[1].config.colour = card.joker_display_values.active and G.C.SECONDARY_SET.Spectral or
            G.C.UI.TEXT_INACTIVE
    end
    return false
end

The children of text and reminder_text are the different text objects.

So, if you have something like this:

text =  {
    { 
        text = "1" 
    },
    { 
        text = "2" 
    },
    {
        border_nodes = {
            { text = "3" },
            { text = "4" },
        } 
    },
    { 
        text = "5" 
    },
}

You can access 2 with text.children[2] and 5 with text.children[4].

Objects inside borders are children of children, so you can access 4 with text.children[3].children[2].

Objects inside extra are the same, but keep in mind that each object is a children of a row, similar to above with border_nodes.

retrigger_function

This function is used to calculate card retriggers caused by the Joker.

Parameters:

playing_card: (table) The Playing Card being calculated. (Will not be debuffed)

scoring_hand: (table?) The hand being (or about to be) scored. nil if poker hand is unknown (i.e. there are facedowns)

held_in_hand: (boolean?) If the card is held in hand and not being played.

joker_card: (table) The Joker Card that's causing the retriggers. (Will not be debuffed)

Returns:

extra_triggers: (number) Amount to extra triggers for that card (or 0 if none).

-- Sock and Buskin
-- Retriggers once if it's a face card.
retrigger_function = function(playing_card, scoring_hand, held_in_hand, joker_card)
    if held_in_hand then return 0 end
    return playing_card:is_face() and 1 or 0
end

mod_function

This function is used to add extra modifiers to other Jokers. I.e. extra chips, X chips, mult, X mult or dollars.

Parameters:

card: (table) The Joker being calculated

Returns:

modifiers: (table) Modifiers to be added. Modifiers can be chips, x_chips, mult, x_mult and/or dollars. You can return multiple.

-- Baseball Card
-- Adds X Mult if Joker is Uncommon
mod_function = function(card)
    return { x_mult = (card.config.center.rarity == 2 and G.P_CENTERS["j_baseball"].config.extra or nil) }
end

Clone this wiki locally