Register

Introduction to Development

Overview

This article provides a guide for users interested in getting started developing their own packages for use in Foundry Virtual Tabletop. We believe in fostering and encouraging new developers and that Foundry VTT can be a great way to teach yourself the basics of JavaScript and other facets of modern web development. While we cannot provide a detailed introductory course to modern JavaScript, FVTT serves as a good framework in which to apply some of the lessons you might learn while completing such a course elsewhere.

If you are reading this article and thinking "I can't do this, I'm not a programmer." This article is intended for you. Many users feel developing their own modules, systems, or even worlds for release as Foundry VTT packages have a high barrier to entry because of a common perception that programming is difficult. However, programming for Foundry VTT, while based on JavaScript, has an extremely low barrier to entry for those willing to learn some basic development practices. This article contains links to some free introductory level courses which you can use to get started, and we feel it is important to emphasize that even an introductory level of JavaScript knowledge is sufficient to make modules and game systems for Foundry VTT.

It is important to credit community member Calego and his helpful Module Making for Beginners article for helping to inspire the approach our development articles use. With his permission, we have reused some of his tutorial to provide concise descriptions of common problems.

If you are an experienced JS developer just looking for deep secrets and arcane knowledge of the API or a quickstart guide to getting your project going, please head directly to Introduction to Module Development or Introduction to System Development as well as the API Documentation.

Before you Begin

Foundry Virtual Tabletop is a web application, and package development in FVTT uses web technologies. Specifically, packages 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.

HTML
Used to define the structure and content of web pages and interface elements.
CSS

Used to define the layout and appearance of HTML elements.

JavaScript

Used to define behaviors and functions, handle underlying data, and provide the underlying framework for interacting with UI elements.

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 package for Foundry Virtual Tabletop will require use of some or all of these techniques. You do not need to be an expert, but it is important to know that this will be a learning process. While you undertake this journey be sure to remain patient and focus on making progress one step at a time. Building your first package will almost certainly take longer than you think, but as you learn your pace of progress should speed up considerably.

Package Types

Foundry Virtual Tabletop has a number of different package types, and before you begin with any project it will be important to know the differences between each.

Game Worlds
primarily used for distributing adventure content intended for use with a particular Game System. Game Worlds are an enclosed package which typically contain all of the Documents needed for a Gamemaster to run a complete adventure or campaign from start to finish for their players. Game Worlds can also contain JavaScript and CSS files which will be loaded whenever that world is loaded, allowing you to provide specific functions and styling that only apply to this particular world.
Game Systems
Generally more in-depth than either of the other packages due to the amount of data most role-playing games require. Game Systems typically include JavaScript files for handling the automation of rules for the game, as well as HTML and CSS to provide the appearance of facets of the game such as character sheets or items.
Add-on Modules
The most common type of package and where most community developers begin. Add-on Modules use JavaScript files to extend and modify the behavior of Foundry Virtual Tabletop and its Game Systems, and HTML and CSS to provide a UI for users to interact with.

Important Questions

Now that you have a brief overview of the landscape, it's important to ask some questions and make some decisions about what your project will look like. These decisions are not set in stone- you can change them later if absolutely necessary, but starting out on a solid foundation will save hours of rework in the long run.

Resources

The following free resources are extremely useful for getting started with development knowledge and should provide you with sufficient skills to begin your project, even if you have no experience with web development.

Note: You do not need to complete all of these in full before beginning your project. You should begin working on your project while taking these courses.

Introductory JavaScript

Introductory HTML

Introductory CSS

Choosing a Development Software

There are an abundance of free options with built-in tools for assisting you as you begin your project, and the only right answer for choosing which suite works best is to identify which one works best for you. MDN Web Docs provides a comprehensive overview of available tools and technologies to get you started.

If you'd prefer to get started quickly, any of the following tools will meet your initial needs:

Common Concepts

Whether you are developing a World, System, or Module, there are some fundamental concepts which apply. As you develop your package, a good understanding of these will help guide your success.

About Git

Git is a software designed to assist developers with version control. As an oversimplification, Git is used to track any changes made to files within your project and maintains all of those files within a repository. Foundry Virtual Tabletop allows users to install packages from Git repositories remotely, which is why you will a vast majority of installation links for Foundry VTT packages are hosted at places like GitLab or GitHub.

Git was designed for handling a lot of complex facets of development, and development for Foundry VTT typically uses only a small percentage of the features Git offers. W3 Schools offers a detailed Git tutorial. For convenience and simplicity, we recommend use of a GUI utility for managing your git repositories such as GitKraken.

About Versioning

A slightly more complex but important facet of development, Foundry VTT uses its own package management system so that the version of your package is the one the user wishes to be using. By versioning your package properly you can leverage some tools from the Foundry VTT API to make code changes to support your package across different versions of the software.

How does Foundry VTT Determine if a Version is Newer?

The helper method isNewerVersion(availableVersion, currentVersion) compares two version fields within the core software or within packages. At a very simplified level, this method compares the two versions and determines which is newer based on the following rules:

  1. If availableVersion has more . deliniated parts than the currentVersion, it is determined to be newer.
  2. The version which is numerically higher is newer. (2 is greater than 1)
  3. An alphabetical character is newer based on its progression in the alphabet. (b is newer than a)

Version Recommendations

There are many ways to assign version numbers to software and content packages as they are being developed. While Foundry VTT supports a number of different options, there are no strong recommendations to be made about any one above another. It should be noted that some common versioning schema that exist contain advanced details which Foundry VTT does not parse as part of its versioning checks.

Incrementing
A newer version has a higher alphanumeric value than a previous one. This is internally how Foundry works, using a form of [Generation].[Build], such as 9.230. This is a simple version scheme that plays well to the strength of Continuous Integration frameworks. Recommended for user-facing packages, such as content and modules.
Example
1 -> 2 -> 3
1.1 -> 1.2 -> 2.0
alpha1 -> alpha2 -> beta1 -> stable1
Semantic Versioning (Semver)

Note: While basic usage is supported, advanced usage such as + or - notation for pre-releases is not.

A popular 3-part versioning schema designed for use in software libraries. Semver follows the form of [Major].[Minor].[Patch]. Recommended for Library packages, Game Systems, or CLI tools.
Example
1.0.0 -> 1.0.1 -> 1.1.0 -> 2.0.0
Calender Versioning (CalVer)

Note: While basic usage is supported, advanced usage such as + or - notation for pre-releases is not.

A date-based scheme where the current date corresponds to the version of the package. This version number can be generated via Continuous Integration frameworks. Recommended for user-facing packages, such as content and modules.
Examples
2022-01-01 -> 2022-02-20 -> 2022-03-12
220101 -> 20220220 -> 20220312

About Namespacing

A high-level concept for programming which applies equally to JavaScript as it does CSS, though in slightly different ways. Namespacing refers to the act of applying specific labels of your choosing to your code in order to ensure that someone else's code does not accidentally use yours by mistake.

For a very simple analogy, imagine working in a large office and your coworker Bill asks you to go grab his lunch from the breakroom refridgerator. Upon arriving, you find five lunch bags labeled "Bill's Lunch" and discover that there are far more people named Bill in your office than you expected. Not knowing which one is the correct Lunch, you grab the first one and bring it back, where you and Bill discover it is not his. If Bill had written his full name on the lunch bag instead of just his first name, identifying the correct one to return with would have been far less confusing.

Correctly namespacing your code is important to prevent confusion. This will likely be detailed more thoroughly by whichever JavaScript or CSS course you choose to undertake.

Namespacing for Javascript

While it is more important to correctly Namespace your code for script-based JS than ES6 Module JS, your JavaScript Functions should ideally be named in way that makes it unique. Foundry VTT takes steps to try to mitigate Namespace issues with its packages, but conflicts can happen. Two packages using "script" declarations instead of ES6 Modules may both define functions in the global scope which can collide and overwrite each other.

Namespacing for CSS

The importance of proper namespacing for CSS definitions is far greater. CSS considers two important factors when applying styles to HTML, the most recently loaded definition and the most specific definition. Using a CSS class definition which isn't specific enough will likely result in your CSS rules applying to an entire part of the program, or cause overlap with other packages. To prevent any unexpected confusion of CSS rules, please adhere to the following best practices:

Use Specific Class and ID Names in HTML

Instead of:


        <div id="selection" class="app">
            <h2 class="header">Make a selection</h2>
          </div>
    

use:


        <div id="my-package-selection" class="my-package my-package-app">
            <h2 class="header">Make a selection</h2>
        </div>
    

Use Specific Selectors in CSS

Instead of:


        .app {
            background-color: gray;
          }
          .header {
            color: red;
          }
    

use:


        .my-package .my-package-app {
            background-color: gray;
          }
          .my-package .my-package-header {
            color: red;
          }
    

By using clear and specific Namespace for your CSS, you can prevent conflict with other packages very easily and keep the package ecosystem healthy for all users.

Flags

All Documents within the Foundry VTT data schema contain a data object called Flags. Flags are intended to store persistent data for modules primarily, but can also be leveraged by world scripts and systems as a place to store data which doesn't necessarily adhere to the data structure provided by a game system.

Flag data is generally stored as a key-value object pair, and each flag should be set using a scope which provides a namespace for the flag to help prevent collisions. Flags set by the core software use the core scope. Flags set by game systems or modules should use the canonical name attribute for the module Flags set by an individual world should "world" as the scope.

Hooks

Hooks are an event framework Foundry VTT uses to provide package developers with the ability to register callback functions that occur at particular times as events within the program occur. For example, the preCreateActor Hook allows you to make changes to the data model for an Actor when its creation process is started but before the Actor is created.

Using A Hook to Log Hooks

One of the most common Hooks to use, init, allows your package to perform actions the moment the program loads a world, before it loads the Canvas or finishes preparing the UI. In the below example, we will provide steps to answer a common question about hooks by using an init Hook.

If using this code snippet, please ensure to remove or comment this function out to prevent generating a large volume of logged messages for users of your package.


    //Use this in your module's primary JS file to log whenever a Hook event occurs.
    Hooks.once("init", function() {
        CONFIG.debug.hooks = true
    }

More about Hooks

Localization

Foundry VTT offers a Localization system in order to provide convenience for translators to work with projects internal to the FVTT application. It’s important to start thinking about localization early in the project, as it is much easier to do it as you develop rather than returning after you have completed the project to add the localization. When developing your project, consider using Localization text everywhere you would normally write text for your users to read. This will mean that other developers wishing to translate your project can do so very easily. For more information, please see Languages and Localization.

The Foundry VTT API

We provide detailed API Documentation for our development community to use. First time developers may find the documentation to be overwhelming at first, but it is broken down into clear categories with increasing levels of detail and examples of usage with each subcategory. Given the level of depth the API documentation provides, beginners should focus on choosing a topic they're interested in exploring from the main index (home) rather than selecting from the quick-reference sidebar. The table of contents at the beginning of the main index is helpfully broken down by major topics.

Some convenient links for the most common API topics:

Using Handlebars

Handlebars is a simple templating language used by Foundry VTT to structure HTML based on JavaScript object data stored by systems, modules, and FVTT itself. You can find out more about Handlebars by clicking here. Handlebars helpers are used in html files to provide ways for your developed Applications, Sheets, or other UI elements a way to interact with or modify data.

The Log Helper

One of the more convenient options helpful for beginner developers is the use of the {{log}} helper


    {{log "!!!!! DOCUMENT DATA !!!!!"}}
    {{log this}}
    <h1>An Example Document, Such as an Actor Sheet</h1>
    <p> Some body text </p>
    <label for="name"> Name:</label>
    <input id="name" type="text"/>

As a default helper included in Handlebars, the Log helper displays in your JavaScript Console the output of JavaScript data. By using log this it will output the data structure of the current Document as Handlebars sees it, making it easy to reference stored data by eliminating any of the guesswork about where that data is stored. By expanding the data object logged to the console, you can explore the data object and locate what needs to be placed as a reference from handlebars.

Foundry VTT includes the following Handlebars Helpers in its API:

{{select}}
Assists in configuring an <option> within a <select> field.
{{checked}}
Assists in configuring a checkbox form input.
{{formatNumber}}
Applies formatting to numbers.
{{timeSince}}
Gets the time that has passed since another time value.
{{filepicker}}
Creates an instance of a filepicker.
{{editor}}
Creates an instance of a tinyMCE editor.
{{localize}}
Adds a localized text string that can be called in order to provide better support for i18n translations.
{{eq}}, {{ne}}, {{lt}}, {{gt}}, {{lte}}, {{gte}}
Logical operation helpers that check if something is equal to, not equal to, less than, greater than, less than or equal to, greater than or equal to.