Skip to content

Developing a System Module

Larkinabout edited this page Oct 24, 2024 · 42 revisions

Introduction

Token Action HUD is a Foundry VTT application generated by two modules: the Token Action HUD Core module and a dedicated Token Action HUD system module (e.g., Token Action HUD D&D5e for the D&D 5e system).

Token Action HUD Core module (TAH Core)

TAH Core drives the Token Action HUD application. It provides base classes for Token Action HUD system modules to extend. The HTML templates and CSS styles are part of TAH Core. TAH Core is also responsible for building out all of the groups and actions that are common to all Foundry VTT systems: compendiums, macros and actions such as making a token visible/invisible and adding tokens to the combat tracker.

Token Action HUD Template

A Token Action HUD system module template is available here: Larkinabout/fvtt-token-action-hud-template

Token Action HUD system modules (TAH system module)

TAH system modules are responsible for building out the groups and actions related to the system. They also define the base layout of the HUD as well as the system-defined groups available to the user.

A TAH system module will have the following at a minimum:

  • An ActionHandler class, which extends TAH Core's ActionHandler class.
  • A SystemManager class, which extends TAH Core's SystemManager class.
  • A callback handler for TAH Core's tokenActionHudCoreApiReady hook.
  • A tokenActionHudSystemReady hook to pass its SystemManager class and its required core module version to TAH Core.
  • A required core module version.

System Module Classes

ActionHandler

Extends TAH Core's ActionHandler class and builds system-defined actions for the HUD.

Required Methods

  • buildSystemActions(groupIds): Called by TAH Core to initiate the build of system-defined actions by the TAH system module.

RollHandler

Extends TAH Core's RollHandler class and handles action events triggered when an action is clicked.

Note

As of Token Action HUD Core 2.0.0, click and hover events associated with an action can also be handled directly by the action's onClick and onHover properties added within the ActionHandler class.

Required Methods

  • handleActionClick(event, encodedValue): Called by TAH Core when an action on the HUD is left or right-clicked.
    • event: The event.
    • encodedValue: The encoded value stored against the button.

Example:

  1. The 'Club' action is clicked on the HUD.
  2. TAH Core calls the TAH system module's handleActionClick method and passes event and encodedValue (e.g., 'item|lbeVmFOH3ZzSRn7V').
  3. The TAH system module decodes encodedValue into its component parts using encodedValue.split(this.delimiter) and passes the result into the variables: actionType and actionId.
  4. The component parts are resolved using if and switch functions to identify the action as an item use.
  5. The item object is retrieved from the actor object using coreModule.api.Utils.getItem(this.actor, actionId).
  6. The item object's use method is called.

Available Methods

  • handleActionHover(event, encodedValue): Called by TAH Core when an action on the HUD is hovered on or off.
    • event: The event.
    • encodedValue: The encoded value stored against the button.
  • handleGroupClick(event, group): Called by TAH Core when a group on the HUD is right-clicked while the HUD is locked. Left-clicking while the HUD is locked is reserved for TAH Core's group toggle and right-clicking while the HUD is unlocked is reserved for opening the group dialog.
    • event: The event.
    • group: The group.

Available Properties

  • action: Object. The action object.
  • actor: Object. The actor object for the controlled token.
  • actors: Array. Array of actor objects for the controlled tokens.
  • delimiter: String. The delimiter character for using in the action's encodedValue. The default is |.
  • isAlt: Boolean. Whether the ALT key was pressed when the button was clicked.
  • isCtrl: Boolean. Whether the CTRL key was pressed when the button was clicked.
  • isHover: Returns a boolean for whether the action is hovered.
  • isRenderItem(): Returns a boolean for whether the item sheet can be rendered.
  • isRightClick: Boolean. Whether the button was right-clicked.
  • isShift: Boolean. Whether the SHIFT key was pressed when the button was clicked.
  • renderItem(actor, itemId): Renders the item's sheet.
    • actor: The actor object.
    • itemId: The item's id.
  • token: Object. The token object for the controlled token.
  • tokens: Array. Array of token objects for the controlled tokens

SystemManager

Extends TAH Core's SystemManager class and used by TAH Core to register the TAH system module's extended classes. This class must be passed from the TAH system module to TAH Core via the 'tokenActionHudSystemReady' hook. TAH Core will then call the following TAH system module methods:

Required Methods

  • getActionHandler: Initialise and return the system module's ActionHandler.
  • getAvailableRollHandlers: Return a list of available roll handlers.
  • getRollHandler: Initialise and return the system module's RollHandler.
  • registerDefaults: Register the system module's default HUD layout and groups.

registerDefaults

The registerDefaults method requires the TAH system module to return an object containing the default HUD layout and the groups available for the user to add to the HUD via the dialogs.

  • defaults: { layout, groups } Default HUD layout and groups
    • layout: [group, group, ...]
      • group: { id, name, nestid, type, groups }
        • id:
        • name:
        • nestId: The nest id. See nestId.
        • type: The group type: system or system-derived
        • groups: [group, ..., ...]
          • group: { id, name, nestId, type, groups }
            • id: The group id
            • name: The group name displayed on the HUD
            • nestId: The nest id. See nestId.
            • type: The group type: system or system-derived.
    • groups: [group, group, ...]
      • group: { id, name, system }
        • id: The group id.
        • name: The group name displayed on the HUD.
        • type: The group type: system or system-derived.

This example code shows the expected format:

{
    layout: [
        {
            nestId: 'inventory',
            id: 'inventory',
            name: 'Inventory',
            groups: [
                { nestId: 'inventory_weapons', id: 'weapons', name: 'Weapons', type: 'system' },
                { nestId: 'inventory_equipment', id: 'equipment', name: 'Equipment', type: 'system' },
                { nestId: 'inventory_consumables', id: 'consumables', name: 'Consumables', type: 'system' }
            ]
        },
        { ... }
    ],
    groups: [
        { id: 'abilities', name: 'Abilities', type: 'system' },
        { id: 'checks', name: 'Checks', type: 'system' },
        { id: 'consumables', name: 'Consumables', type: 'system' }
        { id: 'equipment', name: 'Equipment', type: 'system' },
        { id: 'weapons', name: 'Weapons', type: 'system' },
        { ... }
    ]
}

Available Methods

  • registerSettings(onChangeFunction): Register the system module's settings. Called by TAH Core when registering its own settings.
    • onChangeFunction: This function can be called in the registered settings onChange parameter to trigger TAH Core's own settings update process when a TAH system setting is updated.
  • registerStyles: Register the system module's HUD styles to display in TAH Core's 'Style' module setting. This method requires an object to be returned in the following format:
{
    myFirstStyle: { // Unique ID for the style
        class: 'tah-style-my-first-style', // The class to add to the first DIV element
        file: 'tah-dnd5e-my-first-style', // The CSS filename without the .css extension
        moduleId: 'token-action-hud-dnd5e', // The TAH system module ID
        name: 'My First Style' // The name to display in the setting drop-down list
    },
    mySecondStyle: {
        class: 'tah-style-my-second-style',
        file: 'tah-dnd5e-my-second-style',
        moduleId: 'token-action-hud-dnd5e',
        name: 'My Second Style'
    },
}

tokenActionHudCoreApiReady hook

To extend TAH Core's classes, the TAH system module classes must be wrapped in a callback handler for TAH Core's tokenActionHudCoreApiReady hook. The hook passes TAH Core's module API enabling the TAH system module to access TAH Core's classes and utils. This example code shows the expected format:

export let SystemManager = null

Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
    SystemManager = class SystemManager extends coreModule.api.SystemManager {
        // CODE
    }
})

tokenActionHudSystemReady Hook

A call of the tokenActionHudSystemReady hook to pass its SystemManager class and its required core module version to TAH Core. This example code shows the expected format:

import { SystemManager } from './system-manager.js'
import { MODULE, REQUIRED_CORE_MODULE_VERSION } from './constants.js'

Hooks.once('ready', async () => {
    const module = game.modules.get(MODULE.ID)
    module.api = {
        requiredCoreModuleVersion: REQUIRED_CORE_MODULE_VERSION,
        SystemManager
    }
    Hooks.call('tokenActionHudSystemReady', module)
})

requiredCoreModuleVersion

This is the required core module version in the format: Major.Minor or Major.Minor.Patch, e.g., 1.1. TAH Core's module version is in the format: Major.Minor.Patch, however patch releases should never include breaking changes, therefore Major.Minor should suffice and allow for easy updating of TAH Core patch releases without requiring a corresponding TAH system module release.

Token Action HUD Core Classes

ActionHandler

Builds the action list and saves the HUD's actions to the actor.

Available Methods

  • addGroup(groupData, parentGroupData, update = false): Add a group to the HUD under the given parent group.

    • groupData: Object. { id, name, type, settings, defaultSelected, selected, info1, info2, info3, subtitleClass, system, tooltip }
      • id: String. The group id, e.g., 'weapons'.
      • name: String. The group name as displayed on the HUD.
      • type: String. The group type: 'system' or 'system-derived'.
      • settings: Optional. Object. { characterCount, collapse, showTitle , style }
        • characterCount: Optional. Number. The number of characters to show for each action's name within the group.
        • collapse: Optional. Boolean. Whether to collapse the group on the HUD: true or false.
        • image: Optional. String. The image displayed on the tab group button or next to the list group.
        • showTitle: Optional. Boolean. Whether to show the group's title on the HUD: true or false.
        • style: Optional. String. The group style: list or tab.
      • defaultSelected: Optional. Boolean. Whether the group is shown on the HUD by default: true or false. Default is true.
      • selected: Optional. Boolean. Whether the group is shown on the HUD: true or false.
      • info1, info2, info3: Optional. Object. { class, text, title }
        • class: Optional. String. The CSS class applied to the DIV.
        • text: String. The text.
        • title: Optional. String. The title applied to the DIV.
      • subtitleClass: Optional. String. The CSS class applied to the DIV.
      • system: Optional. Object. Use to store additional properties.
      • tooltip: Optional. Object. { content, class, direction }
        • content: String. The tooltip HTML content.
        • class: Optional. String. A CSS class.
        • direction: Optional. String. Direction to open the tooltip: LEFT, RIGHT, TOP, BOTTOM, CENTER.
    • parentGroupData: { id, type }
      • id: String. The parent group id, e.g., 'inventory'.
      • type: String. The parent group type: 'system' or 'system-derived'.
    • update: Optional. Boolean. Whether to update existing groups. Default is false.
  • updateGroup(groupData, parentGroupData = null): Update existing groups or a group under the given parent group.

    • groupData: { id, name, type, settings, selected, info1, info2, info3, subtitleClass, system, tooltip }
      • id: String. The group id, e.g., 'weapons'.
      • name: String. The group name as displayed on the HUD.
      • type: String. The group type: 'system' or 'system-derived'.
      • settings: Optional. Object. { characterCount, collapse, showTitle , style }
        • characterCount: Optional. Number. The number of characters to show for each action's name within the group.
        • collapse: Optional. Boolean. Whether to collapse the group on the HUD: true or false.
        • image: Optional. String. The image displayed on the tab group button or next to the list group.
        • showTitle: Optional. Boolean. Whether to show the group's title on the HUD: true or false.
        • style: Optional. String. The group style: list or tab.
      • selected: Optional. Boolean. Whether the group is shown on the HUD: true or false.
      • info1, info2, info3: Optional. Object. { class, text, title }
        • class: Optional. String. The CSS class applied to the DIV.
        • text: String. The text.
        • title: Optional. String. The title applied to the DIV.
      • subtitleClass: Optional. String. The CSS class applied to the DIV.
      • system: Optional. Object. Use to store additional properties.
      • tooltip: Optional. Object. { content, class, direction }
        • content: String. The tooltip HTML content.
        • class: Optional. String. A CSS class.
        • direction: Optional. String. Direction to open the tooltip: LEFT, RIGHT, TOP, BOTTOM, CENTER.
    • parentGroupData: Optional. Object. { id, type }
      • id: String. The parent group id, e.g., 'inventory'.
      • type: String. The parent group type: 'system' or 'system-derived'.
  • removeGroup(groupData): Remove a group from the HUD.

    • groupData: {id, nestId}
      • id: String. Use to remove all groups with the matching id.
      • nestId: Optional. String. Use to remove a specific group.
  • addActions(actionsData, groupData): Add a list of actions to the HUD under the given group.

    • actionsData: [{ id, name, encodedValue, cssClass, info1, info2, info3, selected, system, tooltip, onClick, onHover }, {...}]
      • id: String. The action id. Most commonly the item id.
      • name: String. The action name displayed on the button.
      • encodedValue: String. The value passed to the RollHandler when an action is clicked.
      • cssClass: Optional. String. The CSS class applied to the button.
      • icon: Optional. String. The icon displayed on the button in HTML format, e.g., <i class="fas fa-plus" title="Bonus"></i>.
      • img: Optional. String. The image displayed on the button. See Utils#getImage for respecting TAH Core's 'Display Icons' module setting.
      • info1, info2, info3: Optional. Object. { class, text, title }
        • class: Optional. String. The CSS class applied to the DIV.
        • text: String. The text.
        • title: Optional. String. The title applied to the DIV.
      • selected: Optional. Boolean. Whether the action is selected in the HUD: true or false.
      • system: Optional. Object. Use to store additional properties.
      • tooltip: Optional. Object. { content, class, direction }
        • content: String. The tooltip HTML content.
        • class: Optional. String. A CSS class.
        • direction: Optional. String. Direction to open the tooltip: LEFT, RIGHT, TOP, BOTTOM, CENTER.
      • onClick: Optional. Function. Function to execute when the action is clicked.
      • onHover: Optional. Function. Function to execute when the action is hovered.
    • groupData: { id, type }: The group data.
      • id: String. The group id.
      • type: String. The group type.
  • addGroupInfo(groupData): Add group info to an existing group.

    • groupData = { id, type, info }: The group data.
      • id: String. The group id.
      • type: String. The group type.
      • info: Object { info1, info2, info3 } The group info object.
        • info1|info2|info3: Object { class, text, title } The group info.
          • class: Optional. String. The CSS class.
          • text: String. The text.
          • title: Optional. String. The tooltip.

Available Properties

  • actor: Object. The actor object for the controlled token.
  • actors: Array. Array of actor objects for the controlled tokens.
  • characterName: String. The actor's character name.
  • delimiter: String. The delimiter character for using in the action's encodedValue. The default is |.
  • isAlt: Boolean. Whether the ALT key was pressed when the button was clicked.
  • isCtrl: Boolean. Whether the CTRL key was pressed when the button was clicked.
  • isHover: Returns a boolean for whether the action is hovered.
  • isRightClick: Boolean. Whether the button was right-clicked.
  • isShift: Boolean. Whether the SHIFT key was pressed when the button was clicked.
  • token: Object. The token object for the controlled token.
  • tokens: Array. Array of token objects for the controlled tokens

ActionHandlerExtender

Extends the ActionHandler with the extendActionHandler method.

PreRollHandler

Handles action events before passing to the TAH system module.

RollHandler

Registers key presses, handles core-defined actions and calls the TAH system module's RollHandler#handleActionClick.

Available Methods/Properties

  • actor: Object. The actor object for the controlled token.
  • actors: Array. Array of actor objects for the controlled tokens.
  • delimiter: String. The delimiter character for using in the action's encodedValue. The default is |.
  • isAlt: Boolean. Whether the ALT key was pressed when the button was clicked.
  • isCtrl: Boolean. Whether the CTRL key was pressed when the button was clicked.
  • isHover: Returns a boolean for whether the action is hovered.
  • isRenderItem(): Returns a boolean for whether the item sheet can be rendered.
  • isRightClick: Boolean. Whether the button was right-clicked.
  • isShift: Boolean. Whether the SHIFT key was pressed when the button was clicked.
  • renderItem(actor, itemId): Renders the item's sheet.
    • actor: The actor object.
    • itemId: The item's id.
  • token: Object. The token object for the controlled token.
  • tokens: Array. Array of token objects for the controlled tokens.

SystemManager

Intialises core and system classes.

Utils

Provides common functions.

Available Methods

  • checkAllow(userRole): Returns a boolean for whether the user is allowed to use the HUD.
    • userRole: Number. The user role as obtained with game.user.role.
  • deepClone(original, options): A copy of Foundry VTT's deepClone function.
  • getActor(actorId, tokenId): Returns the actor object either from the actor id or token id.
    • actorId: String. The actor id.
    • tokenId: String. The token id.
  • getImage(entity, defaultImages = []): If the 'Display Icons' module setting is enabled, return the image url from an entity (actor, token, item, etc.).
    • entity: Object or String. The entity object (actor, token, item, etc.) or the URL for the image.
    • defaultImages: Array. A list of default images to not return if the entity uses one.
  • getItem(actor, itemId): Return the item object from the actor.
    • actor: Object. The actor.
    • itemId: String. The item id.
  • sortItems(items): Sort items by the sort property.
    • items: The items collection.
  • sortItemsByName(items): Sort items by the name property.
    • items: The items collection.
  • getToken(tokenId): Return the token object.
    • tokenId: String. The token id.
  • getControlledTokens(): Returns a list of controlled token objects.
  • getFirstControlledToken(): Returns the first controlled token object.
  • i18n(toTranslate): A shorthand for Foundry VTT's game.i18n.localize() function.
    • toTranslate: The value to translate.
  • isModuleActive(moduleId): Returns a boolean for whther the module is active. moduleId: String. The module id.
  • getModuleTitle(moduleId): Returns the module's title.
    • moduleId: String. The module id.
  • getModuleVersion(moduleId): Returns the module's version.
    • moduleId: String. The module id.
  • getStatusEffect(actor, statusId): Returns the first matching effect for the actor.
    • actor: Object. The actor.
    • statusId: String. The status id, e.g., 'dead'.
  • getSetting(key, defaultValue = null): Returns the setting's value for the Token Action HUD Core module.
    • key: String. The setting.
    • defaultValue: The default value to return if the setting does not exist.
  • setSetting(key, value): Sets the setting's value for the Token Action HUD core module.
    • key: String. The setting.
    • value: The value to set.
  • getUserFlag(key): Returns the user flag's value for the Token Action HUD Core module.
    • key: String. The flag.
  • setUserFlag(key, value): Sets the user flag's value for the Token Action HUD Core module.
    • key: String. The flag'
    • value: The value to set.
  • unsetUserFlag(key): Unsets the user flag for the Token Action HUD Core module.
    • key: String. The flag.

Logger

Logs messages to the console

Available Methods

  • info(message, notify = false): Log an info message to the console.
    • message: The message.
    • notify: Optional. Whether to notify the user.
  • error(message, notify = false): Log an error message to the console.
    • message: The message.
    • notify: Optional. Whether to notify the user.
  • debug(message, data): Log a debug message to the console where the 'Enable Debugging' module setting is enabled.
    • message: The message.
    • data: Optional. The data to include.

CSS Classes

Token Action HUD Core's CSS stylesheets include classes for use within the action's cssClass or action info's class property.

  • active: Used alongside the toggle class to indicate that an action is active.
  • disabled: Indicate that an action is disabled.
  • tah-spotlight: Color an action's info text. Good for spotlighting specific text when there are several on the action.
  • toggle: Indicate that an action is toggleable.

Styles

Token Action HUD Core has a number of built in styles/themes available for the user to choose from. For TAH System modules or other developers to modify CSS dependent on the core style, the chosen style is added as a HTML class to the HUD's first DIV element. The classes are:

  • tah-style-custom
  • tah-style-dorako-ui
  • tah-style-foundry-vtt
  • tah-style-high-contrast
  • tah-style-pathfinder
  • tah-style-docked-left
  • tah-style-docked-right

Hooks

forceUpdateTokenActionHud

Hooks.callAll('forceUpdateTokenActionHud')

Call this hook to trigger a Token Action HUD update. Most commonly used in TAH system modules in the RollHandler class to update the HUD after handling an action event.

Variables

encodedValue

A pipe-separated list of identifiers built by the ActionHandler and resolved by the RollHandler. Most commonly, encodedValue will include an action type to identify how to handle the action and id to identify the source object. For example, an encodedValue of 'item|lbeVmFOH3ZzSRn7V' identifies the action as an item use (item) and the item object lbeVmFOH3ZzSRn7V. The encodedValue is stored as a string within the HTML button value. All handling is done on the system module side.

nestId

This is a string list of group ids delimited by an underscore (_), e.g., inventory_weapons_ranged. The nestId is generated when a user adds a group and is also required in the TAH system module's default layout.