Spawnable Element

Spawnable elements are a way to define objects that can be spawned by certain actions. They define which objects should be created and what properties they should have. The mod uses the information to pull the correct object and apply the properties to it. Currently they can be used to define the content for the Context Menu as well as for the Spawn Action within a scenario definition.

Defining a Spawnable Element

Each Spawnable Element definition has two required properties: The type of the element (e.g. an obstacle, trap, enemy, etc.) and it’s name. The type tells the mod where to look for the object and the name determines which object from that place it spawns. Both those properties are defined within the element property. To get access to the different types, use the ElementType table in the ResourceApi (as seen in the example).

Example 1. Definition for a Boulder obstacle
local R = require("api.Resource")

local spawnableElement = {
  element = {
    type = R.ElementType.Obstacle,
    name = "Boulder",
  }
}

There are also additional properties that can be set for all elements that support them (most overlays do). E.g. conditions, current/maximum HP or scenario aid tokens.

Example 2. Additional properties for an element
local R = require("api.Resource")

local spawnableElement = {
  element = {
    type = R.ElementType.Obstacle,
    name = "Boulder",
    -- Add the scenario aid tokens A and B to the object
    tokens = {"a", "b"},
    -- Add the Wound condition to the object
    conditions = {"Wound"},
    -- sets the current HP. If hpMax is not used, this is also the maximum HP
    hp = 3,
    -- sets the maximum HP
    hpMax = { "+", "C", 1},
  }
}

The properties hp and hpMax can be a Formula.

Some elements, like traps and enemies, also have additional properties.

Example 3. Definition for a trap with damage and conditions
local R = require("api.Resource")

local spawnableElement = {
  element = {
    type = R.ElementType.Trap,
    name = "Bear Trap",
    conditions = { "Stun" },
    -- Defines the amount of damage this trap does
    damage = 3,
  }
}
Example 4. Definition for a summonable enemy
local R = require("api.Resource")

local spawnableElement = {
  element = {
    type = R.ElementType.Enemy,
    name = "Living Bones",
    -- Spawns at elite difficulty. If not used, "normal" is the default
    difficulty = "elite",
  }
}

Using Spawnable Elements for the Context Menu

To make Spawnable Elements appear in the Context Menu, they have to be added to the ability information of the class or enemy which can create them, by using the spawn property.

For classes this is part of the class information used for registerClass.

Example 5. Definition within a class ability
local ClassApi = require("api.ClassApi")
local R = require("api.Resource")

ClassApi.registerClass("Doomstalker", {
  abilities = {
    ["Detonation"] = {
      level = 1,
      enhancements = {},
      spawn = {
        {
          element = {
            type = R.ElementType.Trap,
            name = "Spike Trap",
            damage = 3,
          }
        }
      }
    },
  }
}

Currently, the element will show up in the Context Menu, if the ability is somewhere present on the table (so not necessarily if it was placed for the current round). The tooltip in the Context Menu will show which ability defined the element, so it’s easier for users to spawn the correct one.

It’s also possible to define Spawnable Elements on the top level of a class definition. Then the element will always show up in the Context Menu regardless of which ability is present. This is useful if the class has lots abilities that spawn the same element. Using the definition in the abilities would clutter the Context Menu with multiple entries of the same element, so this is a way to prevent that.

Example 6. Definition within a class
local ClassApi = require("api.ClassApi")
local R = require("api.Resource")

ClassApi.registerClass("Doomstalker", {
  spawn = {
    {
      element = {
        type = R.ElementType.Trap,
        name = "Spike Trap",
        damage = 3,
      }
    }
  }
})

For enemies this is done in the ability deck definition used for registerEnemyAbilityDeck.

Example 7. Definition within an enemy ability deck
local EnemyApi = require("api.EnemyApi")
local R = require("api.Resource")

EnemyApi.registerEnemyAbilityDeck("Archer", {
  abilities = {
    [7] = {
      image = "...",
      spawn = {
        {
          element = {
            type = R.ElementType.Trap,
            name = "Spike Trap",
            damage = 3,
          },
        }
      },
    },

Defining the elements for bosses works the same, though they use a different API.

Example 8. Definition within a boss
local EnemyApi = require("api.EnemyApi")
local R = require("api.Resource")

EnemyApi.registerBossEnemy("Human Commander", {
  icon = "...",
  spawn = {
    {
      element = {
        type = R.ElementType.Enemy,
        name = "City Guard",
      },
    },
    {
      element = {
        type = R.ElementType.Enemy,
        name = "City Archer",
      },
    },
  }
})
In all instances above, the spawn property is a list of elements, so its possible to put multiple elements in there (as can be seen in the boss example). Be sure to use the correct number of nesting levels of { } even when using only 1 element.

Adding actions

In addition to the element property, Spawnable Elements also have an optional action property, where you can define Actions.

This can be useful, when using the Spawn Action in a scenario definition. E.g. there are scenarios with secret rooms that get revealed when a button is pressed. The button creates a door object to the new secret room, by using the Spawn Action. The action within the Spawnable Element then defines, that the newly spawned door object will really have the "Open" button attached to it. Otherwise it would just be a token.

Example 9. Definition of an overlay that also acts as a door
local spawnableElement = {
  element = {
    type = Scenario.OverlayType.Door,
    name = "Stone Door Horizontal",
  },
  action = {
    -- open Room 2 and 6 of the scenario, when the button is pressed
    rooms = {6, 2}
  },
},

While this is currently only used in scenario definitions, it’s also possible to use that feature for the objects in the Context Menu (a class that can spawn doors, how cool would that be?).

Defining the placement of the new object

The final property of a Spawnable Element is the placement property. This is used to determine where and at what rotation the new object will be spawned at. Is has two properties position and rotation, which each take a 3 dimensional vector of the absolute position/rotation within TTS.

Example 10. Defining the placement of an object
local spawnableElement = {
  element = {
    type = Scenario.OverlayType.Door,
    name = "Stone Door Horizontal",
  },
  action = {
    rooms = {6, 2}
  },
  placement = {
    position = { -3.03, 1.77, 21.00},
    rotation = { 0, 210, 0 },
  },
},

When using the element for the Context Menu this property is not required and actually ignored, because spawning from the Context Menu has it’s own logic to determine the position for the object.

To easily get that information, after you placed an object somewhere on the table, use the Command Line, to print it to the screen (and the Atom console, where you can easily copy it from).