Character Vault
Any Concept / Any System
Your System Come To Life
Roll20 for Android
Streamlined for your Tablet
Roll20 for iPad
Streamlined for your Tablet

Personal tools

Sheet Worker Scripts

From Roll20 Wiki

Revision as of 15:51, 9 November 2015 by Riley D. (Talk | contribs)

Jump to: navigation, search

Sheet Worker Scripts are an advanced feature of the Character Sheets system which allows the sheet author to specify JavaScript which will execute during certain events, such as whenever the values on a sheet are modified.


Adding a Sheet Worker Script

To add a sheet worker script to a Character Sheet, simply add the script into the "HTML" section of the sheet using the following format:

<script type="text/worker">

on("change:Strength", function() {


// ... etc


Note that the script tag must have a type of "text/worker" to be properly handled by the system. When the game loads, all script tags are removed from the sheet's template for security purposes. However, script tags with a type of "text/worker" will be used to spin up a background worker on each player's computer that can respond to changing values in their sheets and take action as needed.

Sheet Workers vs. Auto-Calculating Fields: Which should I use?

There's no hard-and-fast rule about this. Both of these tools are possible of achieving the same thing. Let's take a hypothetical use-case of a "Strength" attribute, which we want to use to keep a "Strength Mod" attribute updated. Here would be the differences between the two tools for this use case:

  • The auto-calculating fields are all re-calculated every time a sheet is opened for the first time. The Sheet Worker fields, on the other hand, only recalculate when their dependent values change. This means that sheets utilizing the Sheet Worker option will be much, much faster for players to open and interact with.
  • In addition, the Sheet Worker calculations run on a background process, meaning that there is no user interface lag created while the calculations are run. Disabled fields, on the other hand, run on the main process and as such can cause "lockups" or "stuttering" if there are large numbers of them being calculated at once (for example, if you have a very complicated sheet using thousands of disabled fields).
  • The auto-calculating Strength Mod field would appear disabled to the player. A Strength Mod field that is updated by a Sheet Worker, on the other hand, would be modifiable after the calculation has run (although any value entered would be overwritten when the Strength value changes). So a Sheet Worker would better support homebrew rules since the player could simply modify the Mod value after Strength changes. On the other hand, the auto-calculating field would not allow such a change, so rules would be "enforced" more rigidly.

In general, our recommendation is that you use auto-calculating fields sparingly. Give yourself a budget of 500 to 1,000 auto-calculating fields at most. We recommend using the new Sheet Worker functionality for most calculations, especially calculations which only need to be performed rarely (for example, your Strength value (and therefore your Strength Mod) probably only changes at most once per session when the character levels up. There's no need to re-run the same calculation over and over again every time the sheet is opened.

Sheet Worker API



This is currently the only supported event. It allows you to listen to the changes of a specific attribute, or in the case of a repeating section any changes in the entire section. It's very straigthforward:

on("change:strength", function() {
   //Do something here

on("change:repeating_spells:SpellName", function() {
   //Do something here

on("change:repeating_spells", function() {
   //Would be triggered when any attribute in the repeating_spells section is changed


getAttrs(attributeNameArray, callback)

The getAttrs function allows you to get the values of a set of attributes from the sheet. Note that the function is asynchronous, which means that there is no guarantee that the order in which multiple getAttrs calls are made is the order in which the results will be returned. Rather, you pass a callback function which will be executed when the values have been calculated. The callback function receives a simple Javascript object with a list of key-value pairs, one for each attribute that you requested.

Here's an example:

on("change:Strength", function() {
   getAttrs(["Strength", "Level"], function(values) {
      //Do something with values.Strength, values.Level

Values in repeating sections require a little special handling. If the event that you are inside of is already inside of a repeating section, you can simple request the variable using its name and you will receive the value in the same repeating section the event was triggered in. For example, if we have a repeating_spells section that has both SpellName, SpellLevel, and SpellDamage, then:

on("change:repeating_spells:SpellLevel", function() {
   getAttrs(["SpellDamage", "SpellName"], function(values) {
      //values.SpellDamage and values.SpellName will both be from the same repeating section row that the SpellLevel that changed is in.

On the other hand, if aren't currently in a repeating section, you can specifically request that value of a field in a repeating section row by specifying its ID manually: