Classes
Components
Class Envelope
The Class Envelope is the infinite bag that contains the Character Box to create new characters for that class.
Lua Script
The Class Envelope should register the class during the onLoad
event.
Details about the data format can be found at registerClass.
If the class also has custom conditions they should be registered here, too (see registerCondition for details about the data structure).
local ClassApi = require("api.ClassApi")
local ConditionApi = require("api.ConditionApi")
function onLoad()
local classData = {
-- ...
}
ClassApi.registerClass("Name of the Class", classData)
-- if the class also has custom conditions, they should be registered here, too
local conditionInfo = {
-- ...
}
ConditionApi.registerCondition("Name of the condition", conditionInfo)
end
Character Box
The Character Box contains all the components for a new character of that class. Each Character Box should contain:
-
The Figure.
-
A deck named
Starting Abilities
for abilities unlocked at level 1. -
A deck named
Advanced Abilities
for abilities that are unlocked at level up. -
A Player Mat
Figure
Name |
Full name of the class. |
Tags |
Required tags will be set automatically through the script. |
Lua Script
Add this script to figure’s script and adjust the shown values to your need.
info = {
hpColour = "#5080C1",
hpTextColour = "#B70F0F",
startingHealth = 10,
}
FrameOffset = 230
require("Figures.CharacterMini")
The value for hpColour
is the background color of the HP bar over the figure.
Similar hpTextColour
is the color of the text appearing on the HP bar.
This is optional and defaults to black.
startingHealth
is the HP value for the character on level 1.
The FrameOffset
is the position where the HP bar will appear relative to the figure.
The correct value can be found by experimenting a bit and see what looks good.
Stances/Resources
info = {
hpColour = "#5080C1",
hpTextColour = "#B70F0F",
startingHealth = 10,
stances = {
{
label = "First Stance",
color = "Red",
textColor = "Black",
},
{
label = "Second Stance",
color = "Blue",
textColor = "Black",
},
{
label = "Third Stance",
color = "Green",
textColor = "Black",
}
},
startingStance = 2,
resources = {
{
name = "Resource 1",
starting = 0,
max = 5,
color = "Red",
textColor = "Black"
},
{
name = "Resource 2",
starting = 3,
max = 5,
color = "Blue",
textColor = "Black"
},
-- up to 3 resources are supported
}
}
FrameOffset = 230
require("Figures.CharacterMini")
Character Sheet
Name |
Character Sheet |
Use the Character Sheet Creator to generate the required script for the character sheet.
Ability Cards
Name |
Name of the ability followed by its initiative value |
Description |
Full name of the class. |
The initiative value of a card has to be a two-digit number enclosed by parentheses (e.g. Perverse Edge (08)
).
When an ability has multiple initiative values (like the Blinkblade from Frosthaven), multiple parentheses can be used.
The initiative tracker then shows all of them and users can remove them if needed.
Within the class box the ability cards then need to be placed into a deck.
The deck needs to be named Starting Abilities
for abilities that are unlocked by the class at level 1.
All those cards will be put the players' hand when a new character is created.
All other ability cards need to be in a deck named Advanced Abilities
.
This ensures that the Campaign Manager can correctly find them.
Lua Script
Abilities only need a script, when it’s an ability that can spawn Summons. The script adds a button to the card that can be clicked and creates the Summon figure. The Summon also needs to be registered accordingly.
local SummonCard = require("Component.SummonCard")
SummonCard.forSummon("Rat Swarm", SummonCard.Position.GHTop, "http://imageurl.com/example1")
Change the name of the first parameter to the name of the Summon this card will spawn.
The second parameter is the position of the button that will appear.
SummonCard.Position
contains the default values for Gloomhaven and Frosthaven abilities and items you can use: GHTop
, GHBottom
, FHTop
, FHBottom
and Item
.
The third parameter is a thumbnail image for the summon to be used in the Context Menu.
Summons
Name |
Unique name across all Summons. |
Tags |
Required tags will be set automatically through the script. |
Summons need to be inside a Custom Content Box to be registered correctly.
Lua Script
Add this script to a Summons' figure script and adjust the shown values to your need.
stats = {
health = 2,
move = 3,
attack = 0,
range = 0,
attributes = {}
}
info = {
hpColour = "#AD735C"
}
FrameOffset = 230
require("Figures.Summon")
The stats
table describes the base stats for the Summon.
The values should be self-explanatory.
The attributes
table describes the default attributes the summon has (like flying, shield or infusing an element).
The format is the same as for Enemy Stats.
The info
table and the FrameOffset
use the same format as the one for the class Figure.
Extra Components
Within the class envelope LUA, you can define other objects contained in the tuck box to automatically unpack with the class. This function takes two parameters: * The NAME of the object * The TARGET area within the player zone where the object should be placed * Valid values for TARGET are "Hand", "HandTwo", "CharacterMat", and "CharacterSheet" * You can specify a specific position relative to their target
To easily get the position in the local coordinate system you can place the object where you want it and then paste that into the chat window:
--Replace "targetObjectGUID" with the GUID where you want to place your object (e.g. the Player Mat) and "objectGUID" with the GUID of the extra object
/execute print(logString(getObjectFromGUID("targetObjectGUID").positionToLocal(getObjectFromGUID("objectGUID").getPosition())))
An example looks as follows:
extra = {
{
name = "Special Rules",
target = "CharacterSheet",
},
{
name = "Special Overlay Tokens",
target = { PlayerMat = { 1, 0, 1 }}
},
},
Registration
Registration of the class is done via the ClassApi.registerClass
function.
This function takes two parameters:
* The name of the class
* The information about the class, like abilities, perks, etc.
An example looks as follows:
local ClassApi = require("api.ClassApi")
function onLoad()
ClassApi.registerClass("Brute", {
-- The GUID of the Class envelope object.
-- Since the registration script is on the envelope itselt, it can be referenced here
boxGuid = self.getGUID(),
-- Number of HP per level
-- Default values are available in ClassApi.HpProgression with Low, Medium and High
hp = ClassApi.HpProgression.High,
-- Definition for the tracker image
tracker = {
-- Link to the Asset for the tracker image
image = "http://cloud-3.steamusercontent.com/ugc/83722391140264566/DC437F88C225F04C6CCE924EA4C3BB31FCD3F3A9/",
-- any other property that is available to conditions can be used, too, e.g. max to make the tracker stackable
},
-- List of perk information
perks = {
[1] = { remove = { "(-1)", "(-1)" } },
[2] = { add = { "(+1)" }, remove = { "(-1)" } },
-- Perks 3 .. 14 would be here too
[14] = { add = { "(+1)" }, ignore = ClassApi.PerkType.IgnoreItem },
[15] = { ignore = ClassApi.PerkType.IgnoreScenario },
[16] = { unlock = "Perk 16 Reminder Cardname" },
-- up to 18 perks are supported (for Frosthaven support)
},
abilities = {
["Eye for an Eye"] = {
level = 1,
enhancements = {
[1] = { position = { -0.46, -0.92 }, multi = false, side = "T", main = true, type = ClassApi.AbilityType.Retaliate },
[2] = { position = { -0.35, 0.53 }, multi = false, side = "B", main = true, type = ClassApi.AbilityType.Heal },
[3] = { position = { -0.50, 0.55 }, multi = false, side = "B", main = true, type = ClassApi.AbilityType.Heal },
}
},
["Brute Force"] = {
level = 3,
enhancements = {
[1] = { position = { -0.06, -0.75 }, multi = true, side = "T", main = true, type = ClassApi.AbilityType.Attack },
[2] = { position = { -0.25, -0.78 }, multi = true, side = "T", main = true, type = ClassApi.AbilityType.Hex, baseHex = 3, otherHex = { 3 } },
[3] = { position = { -0.26, -0.40 }, multi = true, side = "T", main = true, type = ClassApi.AbilityType.Hex, baseHex = 3, otherHex = { 2 } },
[4] = { position = { -0.41, 0.67 }, multi = false, side = "B", main = true, type = ClassApi.AbilityType.Shield },
}
},
},
})
end