This page provides an overview of the basic steps required to create a Module which can be activated to extend and modify the behavior of Foundry Virtual Tabletop and it's game systems. At a conceptual level, think of each Module as a "plug-in" or "add-on" which changes the software behavior in small (or large) ways. Modules can alter the behavior of the core software in several different ways:

Content
Modules which add data in the form of compendium packs of Actors, Items, Scenes, Journal Entries, Roll Tables, or Playlists.
Interface
Modules which change the way the UI looks or behaves, changing the aesthetics and user experience of the software.
Functionality
Modules which add entirely new functionalities or features which do not exist in the base software, or modules which change the behavior of core features so they behave differently.
Translation
Modules which add support for translation of text displayed in Foundry VTT into other languages.

Each module could include one or more of these types of modifications, and users can mix-and-match multiple modules (provided they are compatible) to achieve a high degree of customization for their Foundry VTT experience. This page goes into detail about how module development works for developers who are interested in creating their own module content.


Before you Begin

Foundry Virtual Tabletop is a web application, and module development in FVTT uses web technologies. Specifically, modules rely upon four primary technologies which each serve an important role: HTML, CSS, JavaScript, and JSON. If you are new to web development - Foundry Virtual Tabletop can provide an excellent opportunity to learn these skills while creating something fun and useful for your roleplaying game table. There are an abundance of resources and training courses for learning this technology, the following links provide a simple place to start.

HTML
Used to define the structure and content of web pages and interface elements. Visit Structuring the web with HTML to begin learning more about HTML.
CSS

Used to define the layout and appearance of HTML elements. Visit Learn to style HTML using CSS to begin learning more about CSS

JavaScript

Used to define module behaviors, handle underlying data, and provide interactivity for UI elements. Visit JavaScript - Dynamic client-side scripting to begin learning more about JavaScript.

JSON

A universal data storage format which is used to store and transfer data used by web applications. Visit JavaScript Object Notation (JSON) to begin learning more about JSON.

Building a module in Foundry Virtual Tabletop will require use of some or all of these techniques. You do not need to be an expert - but understanding the basics will be critical. While you undertake this journey be sure to remain patient and focus on making progress one step at a time. Building your first module will almost certainly take longer than you think, but as you learn your pace of progress should speed up considerably.


Module File Structure

A Module is defined as a uniquely-named subfolder folder within {userData}/Data/modules which contains a manifest file in JSON format named module.json which defines the module and describes what features it contains. For the purpose of this example, let's create a module named dice-tray. The first step of your module development should be to define the manifest file and ensure that your module is recognized as valid by the Foundry VTT software.

The bare minimum in order for a module to be recognized by Foundry VTT is a file structure that looks like this:

{userData}/Data/modules/
  dice-tray/
    module.json

In addition to this minimum requirement, you are free to choose the structure of content included inside your module folder - but we recommend adhering to the following boilerplate directory structure with named directories for templates containing HTML templates, scripts containing JavaScript code, styles containing CSS stylesheets, packs containing included Compendium content, and lang containing localization and translation files.

{userData}/Data/modules/
  dice-tray/
    module.json
    templates/
    scripts/
    styles/
    packs/
    lang/

As an example of a complete module which includes many different features, imagine that our example module named dice-tray provides a new UI element for rolling dice inside the VTT. The file structure for such a module might look something like this:

{userData}/Data/modules/
  dice-tray/
    module.json
    artwork/
      d4-icon.png
      d6-icon.png
      d8-icon.png
      d10-icon.png
      d12-icon.png
      d20-icon.png
    templates/
      dice-roller.html
    scripts/
      roller.js
    styles/
      roller.css
    packs/
      rolltables.db
    lang/
      en.json

Remember, apart from the module.json file, you are free to organize your module however you like. These are simply recommendations.


The Module Manifest

Each module must inclide a module.json file which defines the module and specifies what content it includes. This file is required and must be included at the root level of your module folder. The "name" attribute in the manifest file must match exactly with the name of the module folder. The manifest file is a JSON document containing an object of keys and values. A very minimal example of a valid module.json file is the following:

{
  "name": "dice-tray",
  "title": "Dice Tray - An Example FVTT Module",
  "description": "A simple module created as a demo for working in the Foundry Virtual Tabletop framework.",
  "author": "Atropos",
  "version": "1.0.0",
  "minimumCoreVersion": "0.5.0"
}

The above manifest file is sufficient for the module to be recognized, displayed, and enabled within Foundry VTT. The module would not do anything because we have not included any content - but this is a good place to start to make sure that your module is recognized by the system before advancing further.

Hint: JSON files have very specific syntax requirements. Your JSON manifest file must be valid in order for your module to be recognized and loaded. Use the JSON Lint tool to validate that your JSON file is correct if you encounter any issues.

The manifest file can include many attributes, some of which are required while others are optional.

Required Manifest Attributes

name

Choose a unique module identifier. This must be an all lower-case string with no special characters and should use hyphens (not underscores) to separate multiple terms. This name must match exactly with the name of your module directory.

title

Provide a human readable title for the module which is displayed as the visible name for the module in the Setup menu and elsewhere.

description

This field can contain a more lengthy description of the module. This text can be used to describe the functionality, list contact information, provide recommendations to contributors or testers, or any other information you feel is important to provide. This field can contain HTML to structure and style your text.

version

The module version number can be a number or a string which denotes the version of your module. We recommend using the Semantic Versioning schema but this is not strictly required. When making changes to your module, incrementing the version number in your manifest file is used to signal to users that an update is available.

author

Provide your name as the system creator. This field can be any string if you wish to include an email address or other contact information also. Instead of providing an "author" entry you may instead choose to use the expanded authors key which can provide more data and is useful for group authored modules.

minimumCoreVersion

Specify the minimum Foundry Virtual Tabletop version which is required in order for this module to function properly. Sometimes changes or improvements to the core software code will necessitate changing this indicator to ensure that module users are able to utilize this module's features. If a user has a core FVTT version which is older than the specified minimum core version, the module will not be able to be installed unless the user first updates the core software.

Optional Manifest Attributes

compatibleCoreVersion

Specify the latest Foundry Virtual Tabletop version with which this module's features are confirmed to function properly. This field provides a way to signal to module users that a module is safe to use with a certain core version. While it is possible to set this field to any value, including future VTT version numbers which do not exist yet, please use this field responsibly and only denote compatibility with core versions which have been tested and confirmed. If a user is using a core FVTT version which is more recent than the specified compatible core version, the module can be installed and used but will display a warning that it may not function properly.

scripts

An array of JavaScript file paths which should be included whenever this module is being used. Each listed script path should be relative to the module root directory. All scripts which exist will be automatically included in the game session and loaded in their listed order.

esmodules

In addition to including traditional JavaScript script files, you may also include JS files which use the newer ES6 modules specification. As with Scripts, this should be declared as an array. These files are identified separately in the manifest so they may be correctly loaded as a module rather than a script.

styles

You can designate an array of CSS files which should be included in the game session whenever this module is used. Each listed stylesheet path should be relative to the module root directory. All stylesheets which exist will be automatically included in the game session and loaded in their listed order.

packs

Modules may come bundled with Compendium packs which include game content for various Entity types. Compendium packs are defined as objects which have their own internal metadata structure. Please see the Compendium Packs documentation page for details on the Compendium JSON definition. For example:

"packs": [
    {
      "name": "pack-name",
      "label": "Pack Title",
      "system": "system-name",
      "path": "./packs/pack-name.db",
      "entity": "Item"
    },
]
dependencies

Modules can require other modules, systems, or worlds be installed to allow their use. If a module has been installed with dependencies, but its dependencies are missing, it cannot be enabled. Dependencies are defined as an array of objects containing the following data:

name

Dependency entries require the name attribute. If only a name is provided, additional details about the module will be discovered from the Foundry VTT website listing.

type

The type attribute instructs Foundry that the dependency may be on a different type of module. By default dependencies are assumed to be module, so if you want to depend on a system or world you should be explicit.

manifest

The manifest attribute provides an explicit manifest url to be used for downloading the dependency. If a manifest is not provided, the dependency package must exist in the Foundry website directory.

Example structure here:


"dependencies": [
	{
	  "name": "system1",
	  "type": "system"
	},
	{
	  "name": "world1",
	  "type": "world"
	},
	{
	  "name": "module1",
	  "manifest": "https://web/location/module1/manifest.json",
	},
	{
	  "name": "module2"
	}
]
languages

The game system may designate an array of languages specifications that it supports by default. Each element in the languages array is an object which defines the language tag, label, and path to its localization file. Please see the Languages and Localization documentation page for details on language entries provided by a module. For example:

"languages": [
    {
      "lang": "en",
      "name": "English",
      "path": "lang/en.json"
    }
]
system

A system ID or array of system IDs which are required in order to use this module. For example, specifying "system": "dnd5e" will only allow the module to be used by Worlds which are running the dnd5e game system.

authors

Instead of listing a single author name you may instead provide an array of authors, each of which is an object that can contain the keys name, email, and url. For example:

"authors": [
    {
      "name": "Atropos",
      "email": "admin@foundryvtt.com",
      "url": "https://foundryvtt.com"
    }
  ]
  
socket

A module may request for a specialized socket namespace to be provided which allows data messages to be passed between connected clients. If set to true, a socket event will be handled by the server with the event name module.{name}. This event name relays arbitrary data packets between the sending client and all other connected clients. [TODO Example]

url

A public URL that links to the repository or documentation pages for the module. This link will be displayed for users to allow them to find more information about your system. If your module is hosted in version control like GitHub or GitLab, linking to the repository in this field is a good choice.

manifest

A stable URL that describes the latest release version of your manifest file. This URL is used for automatic system installation in the Foundry VTT setup screen. This manifest URL is consulted during the system update check to see whether a new version is available for download. It is important that this address remain stable, otherwise updates will not be detected.

download

A public URL that provides a zip archive of the module for the manifest version which poijnts to it. The archive at this URL is retrieved during the installation or update process. If you are using version control for your package - it is recommended to manage download archives using the tags and releases features which are supported by most git repositories.

license

A path to a license file relative to the root module folder or a publicly accessible URL which contains the software license that applies to this package.

readme

A path to a read-me file relative to the root module folder or a publicly accessible URL which contains instructions or information about the package.

bugs

A publicly accessible URL where issues, suggestions, and bug reports may be filed.

changelog

A publicly accessible URL where update and release notes about the package may be found.


Including JavaScript

For many modules which want to expand or modify core software functionality is to include a JavaScript file (or module) which can introduce programmatic behavior into the Foundry VTT environment. An ideal second step once you have populated your module manifest with the required fields is to create a "Hello World" script which is loaded when your module is active. Experiment with adding a script file to the "scripts" attribute of the manifest. Suppose we create the JavaScript file in our example module dice-tray/scripts/roller.js. We would modify the module.json file as follows and the contents of our created JavaScript file will be automatically loaded and parsed by the browser when a game is loaded.

"scripts": [
  "scripts/roller.js"
]

Note that modules can only affect the game view itself - and not the Setup or Join screens for security reasons.

The example below provides a very simple "Hello World" script which is designed to introduce how scripts are loaded and executed. Open the Developer Tools by pressing F12 and consult the Console tab. Note that in the below example - the statements are logged at different points in time. Depending on what scope of data you need to operate on - you may want to condition execution of module code on certain events (called "hooks") which allow for module logic to interrupt, augment, or replace the default behavior of the VTT platform.

console.log("Hello World! This code runs immediately when the file is loaded.");

Hooks.on("init", function() {
  console.log("This code runs once the Foundry VTT software begins it's initialization workflow.");
});

Hooks.on("ready", function() {
  console.log("This code runs once core initialization is ready and game data is available.");
});

Further Reading

As you delve further into the world of module development - the following topics may prove useful for a variety of tasks you wish to perform.

The below "topics" are a skeleton structure for now - but will link to real documentation pages in the future.