#[OUTDATED] Making your own Jokers with Steamodded's Joker API

19 messages · Page 1 of 1 (latest)

ember pebble
#

This thread will cover the basics of making your own Joker with Steamodded's Joker API.

#

Joker Initialization

You can initialize a Joker by using the SMODS.Joker:new() function.

local joker = SMODS.Joker:new(name, slug, config, spritePos, loc_txt, rarity, cost, unlocked, discovered, blueprint_compat, eternal_compat, effect, atlas, soul_pos)
  • name: The name of the Joker in the code.
  • slug: The unique identifier of the Joker. After initializing the Joker, j_ will be prepended to the slug. For example, if your slug is polydactyly, it will be j_polydactyly after initializing.
  • config: The configuration of your Joker. This is commonly used for storing variables specific to that Joker. For example, Stuntman's config is {extra = {h_size = 2, chip_mod = 250}}, which stores the hand size loss and the chips increase. It is recommended to use a table with an extra key that is an integer or a table, like {extra = 3}.
  • spritePos: The position on the atlas that will be used for the Sprite. This will be explained later.
  • loc_txt: The localization text of the Joker. It is a table following this format:
{
  name = "Polydactyly", -- The Joker's name
  text = {
    "Choose an extra card", -- The Joker's description, each string in the table will be on a new line
    "from {C:attention}Booster Packs{}", -- You can also highlight the text on the Joker, explained later
  }
}
  • rarity: The rarity of the Joker. 1 is Common, 2 is Uncommon, 3 is Rare and 4 is Legendary. Custom rarities will not be covered.
  • cost: The cost of the Joker.
  • unlocked: Whether the Joker will be unlocked by default. The API doesn't support checks for unlocking Jokers as of now, so this should be set to true.
  • discovered: Whether this Joker will be discovered by default, showing its name when hovered over.
  • blueprint_compat: Whether this Joker will be shown as "compatible" to Blueprint or Brainstorm when hovered over. Note that this does not prevent a Joker from being copied by them.
#
  • eternal_compat: Whether this Joker can be generated with the Eternal sticker.
  • effect: yeah idk what this does either
  • atlas: The name of the spritesheet, or atlas, the Joker will take its sprites from. This will be explained later.
  • soul_pos: Same as spritePos, but for overlaying a floating sprite on top of the original Joker. This is used for Hologram and the Legendary Jokers.

After initialization a Joker, you'll need to register it to the mod loader by using the register() function.
This is the code for Polydactyly, with comments for each variable:

local localization = { -- Localization is a separate variable so it won't look cluttered when registering
  name = "Polydactyly",
  text = {
    "Choose an extra card",
    "from {C:attention}Booster Packs{}",
  }
}

local joker = SMODS.Joker:new(
  "Polydactyly", -- name
  "polydactyly", -- slug
  {extra = 0}, -- config
  {x = 0, y = 0}, -- spritePos
  localization, -- loc_txt. The table we declared just now is passed through this
  2, -- rarity, 2 is Uncommon
  6, -- cost
  true, -- unlocked
  true, -- discovered
  false, -- blueprint_compat
  true, -- eternal_compat
  "", -- effect
  "MystJokers", -- atlas. The Joker will take its sprites from the atlas called "MystJokers"
  -- We do not declare a soul_pos because we do not need one
)
joker:register()
#

Setting Sprites

After the Joker is initialized, we'll need to give it some sprites.
Steamodded will look for sprites in the [mod name]\assets\1x and [mod name]\assets\2x folders. There is no limit to how big the spritesheets are, however, the Jokers are 71x95 by default on 1x. The sprites should be scaled up in the 2x folder.

To initialize a sprite, use SMODS.Sprite:new()

local sprite = SMODS.Sprite:new(name, top_lpath, path, px, py, type)
  • name: The name of the atlas.
  • top_lpath: The path to look for sprites. Steamodded provides a function SMODS.findModByID(mod_name).path to easily set this variable. mod_name should be the same as the MOD_ID declared in the Steamodded header.
  • path: The name of the spritesheet file.
  • px: The width of a sprite in the spritesheet. For Jokers, this is 71.
  • py: The height of a sprite in the spritesheet. For Jokers, this is 95.
  • type: The type of a sprite. For static Jokers, this is "asset_atli". Animated Jokers will not be covered in this guide.

And for the variables that we haven't covered in the last section:

  • atlas: This should be the same as the name declared in the SMODS.Sprite:new() function.
  • spritePos: {x = 0, y = 0} refers to the sprite in the top-left of the spritesheet. Increasing the x value moves the selected sprite one column to the right, while increasing the y value moves the selected sprite one row down.
#

For example, this is part of the spritesheet used in Balatro.
A spritePos of {x = 0, y = 0} refers to the 71x95 area in the top-left of the spritesheet, which is also Joker's sprite.
To get Acrobat's sprite (bottom-right), we increase x by 2 and y by 1 (the sprite is two columns and one row away from Joker). We would have a spritePos of {x = 2, y = 1}.

#

After initializing the sprite, you must register it similar to Jokers, using the register() function.

To initialize Polydactyly's sprite:

local sprite = SMODS.Sprite:new("MystJokers", SMODS.findModByID("MystJokers").path, "polydactyly.png", 71, 95, "asset_atli")
sprite:register()

As polydactyly.png only has one sprite, we can set spritePos of the Joker to {x = 0, y = 0}.
(Polydactyly art by Etikeki)

#

Joker Effects

Steamodded provides two functions to code your Joker effects, and two functions to display their effects.

#

set_ability

This function is called once whenever the Joker is generated (in Shop, from Booster Packs, in the Collections menu, etc.), when the Card:set_ability function is called in the vanilla code.
To set a Joker's ability, use SMODS.Jokers.[slug].set_ability = function(self, center, initial, delay_sprites). slug should be the same as the one declared in your Joker, with j_ as the prefix.

For example:

SMODS.Jokers.j_polydactyly.set_ability = function(self, center, initial, delay_sprites)
  self:set_edition({negative = true})
  self.ability.eternal = true
  self.ability.extra = #G.jokers.cards
end

What this snippet of code does is that whenever Polydactyly generates, it will become a Negative and Eternal card. In addition, it will save the amount of Jokers you have when it generated to its extra variable.
Note that we use self.ability.extra and not self.config.extra like when the Joker is declared.

#

calculate

This function is called whenever the Joker does its calculation, when the Card:calculate_joker function is called in the vanilla source code.
Use SMODS.Jokers.[slug].calculate = function(self, context) for this.

For all the contexts and when they are used, refer to the original function in the vanilla source code.
Steamodded provides a function SMODS.end_calculate_context(context) for Jokers that trigger when a hand is calculated.

For example:

SMODS.Jokers.j_polydactyly.calculate = function(self, context)
  if SMODS.end_calculate_context(context) then
    if self.ability.extra > 0 then
      return {
        message = localize{type = 'variable', key = 'a_mult', vars = {self.ability.extra}},
        mult_mod = self.ability.extra,
      }
    end
  end
end

What this snippet of code does is that whenever a hand is played and Jokers give out effects, it will add Mult equals to self.ability.extra if it's greater than 0.
The message is used to display the "+x Mult" text that pops out when the Joker is triggered.

#

loc_def

This function is used to replace variables in the Joker's description.

For example, with this localization:

{
  name = "Autism Creature",
  text = {
    "{C:mult}+6{} Mult for each",
    "empty {C:attention}Joker{} slot",
    "{C:inactive}(Currently {C:mult}+#1#{C:inactive} Mult)"
  }
}

there is a space to include a variable (#1#).

Use SMODS.Jokers.[slug].loc_def = function(self):

SMODS.Jokers.j_autism_creature.loc_def = function(self)
  return { self.ability.extra }
end

which will replace the #1# with the value in self.ability.extra.
For #2#, #3#, etc., add more variables to the returned table {self.ability.extra.value_1, self.ability.extra.value_2, ...}.

#

tooltip

This function is used to show a small infobox next to the Joker when it is hovered.

Use SMODS.Jokers.[slug].loc_def = function(self):

SMODS.Jokers.j_lucky_seven.tooltip = function(self, info_queue)
  info_queue[#info_queue+1] = G.P_CENTERS.c_wheel_of_fortune
end

This will add the The Wheel of Fortune's info when the Joker is hovered over. This function is recursive, so it will also display the effects of Foil, Holographic and Polychrome from The Wheel of Fortune.
You can also append to the info_queue variable a table with a key and set:

SMODS.Jokers.j_polydactyly.tooltip = function(self, info_queue)
  info_queue[#info_queue+1] = G.P_CENTERS['e_negative']
  info_queue[#info_queue+1] = {key = 'eternal', set = 'Other'}
end
#

Other Notes

All Joker functions need to be defined in your mod's SMODS.INIT.mod_id() function, for example:

function SMODS.INIT.MystJokers()
  local joker = ...
  local sprite = ...

  SMODS.Jokers.j_polydactyly.calculate = function(self, context)
    ...
  end
end

Feel free to ask around in #⚙・modding-general if you're still unsure about anything!

Portals to each section:
Joker Initialization: #1228599493914656788 message
Setting Sprites: #1228599493914656788 message
Joker Effects: #1228599493914656788 message

Please do not send any message in the thread. To join the thread without sending a message, right click the thread name and press "Follow Post".

clear lotus
#

I'm not sure what I'm missing, but I've tried invoking set_edition in various ways, and it errors out because it can't find a set_edition

ember pebble
#

shit is outdated as hell lmao

#

[OUTDATED] Making your own Jokers with Steamodded's Joker API

native ledge
ember pebble
native ledge
#

ok

clear lotus
#

Well I've been trying to do it in the table notation, not with a constructor; but I can't get it to create the joker as always negative - is there a field for that? Or what do I call where/when with set_ability? Nothing I find in code works