What Is Character Sheet Templating?

I originally created this chapter, naively thinking I’d create a series describing how to use sheet templating. Now that I’ve thought about it, I realise that was a fool’s errand. I’d better explain why, and what sheet templating actually is.

The Purpose of Sheet Templating

The basic idea: recognise there’s a lot of duplicated code in a typical Character Sheet, and computer programs are really good at churning out verbose code that follows a template.

Take a look at a typical Roll20 character sheet, especially the HTML page. For example, let’s say you have a section showing 6 attributes. It might look like this:

<div class="stats">
    <h2>Display of Stats</h2>
    <input type="number" name="att_str" value="10">
    <span>Str Mod</span>
    <input type="number" name="att_str_mod" value="0">
    <input type="number" name="att_dex" value="10">
    <span>Dex Mod</span>
    <input type="number" name="att_dex_mod" value="0">
</div>Code language: HTML, XML (xml)

Thats just the first 2 stats, imagine there were 4 more. The code would be very long, but would look very similar. Now, imagine instead you could write:

div stats
   h2 Display of Stats
   stats = [Strength Dexterity Constitution Intelligence Wisdom Charisma]
   input <3-letter>
   span +Mod
   input <3-letter>_modCode language: Markdown (markdown)

And imagine have a separate program you feed that into, and it churns out the code in the first block above. You can easily see how that might happen. The code for each stat is the same as the other 5 stats with a few minor differences. Give your code a template for one stat and describe those variations, and it churns out the full detail.

Now imagine doing the same for skills, saving throws, and anything else that might have multiple copies of the same thing on the character sheet.

That is essentially sheet templating: create a template, provide the variations, and let another program build your character sheet for you.

It’s not always quite as straightfoward, but there are several methods that people use to streamline the code writing. I’ll describe them here and you can use them as jumping off points to explore in your own time.

Methods of Templating

Not all the methods here are full “templating”, but they all do a similar thing: enable you to shortcut the process of writing your code and easily handle duplicated areas.

0. AI and chatGPT

An obvious question to ask, is why not create your code with AI? The answer is simple: you can’t, and probably never will be able to.

AI, more properly termed Large Language Model, is a way of of taking in vast amounts of data, and using a form of statistic analysis, to create your code. The emphasis here is on the words Large and vast. There are many things AI can do, but writing Roll20 code is one of the things it will never be good at. Roll20 code is subtly different from standard HTML and JS, and there will never be enough for AI to work with. Learn more here. So this should be avoided when writing Roll20 code , which is why it’s numbered 0.

If you could use AI, including chatGPT, this page would be a lot shorter.

1. Macros

Nearly all complex programs have a “macro” system: these convert keyboard shortcuts into some other output, which can be lines of code. For example, when typing a in microsoft word, it’ll autocorrect it to A. You can take control of autocorrect and tell it when you type input it’ll autocorrect it to <input type = “” name=”attr_” value=”” > and then you can fill in the rest. It’s a time-saver.

If you use visual code, there’s an extension called Roll20 Sheet Dev which has a lot of roll20 substitutions already created. Let’s say I am creating a checkbox. If I type in:c at the start of a line, I see a popup menu like this (exactly what shows depends on the extensions you have installed):

Notice that when I select in:c, it shows what will appear way out on the right. I now press tab, and the following text is autofilled:

The complete code for a checkbox is created, but also the cursor is in two places – after the attr_ and inside @{}. I can type one word and it is placed in both places.

This extension makes creating code a lot faster. The in:c is just one example – if you use the extension, you’ll find a lot more (for most of the types of HTML you create).

So there you have it, macros allow you to enter code a lot more rapidly with a few keyboard shortcuts. But using macros isn’t really true templating (but you can use them alongside any of the templating techniques described below!).

2. Brute Force, Or Writing Code with a Spreadsheet

You can create your own version of sheet templating, using a programming language or even common tools like Microsoft Excel or Google Sheets. I used to do this before I knew there were programs that already did this.

The trick is noticing that lots of code in a typical sheet is duplicated. Notice how a typical sheet worker always has several lines in common:

on('change:stat1 change:stat2',  function() {
   getAttrs(['stat1', 'stat2'], function(values) {
      // do some calculation with stat1 and stat2

         stat3: stat3
Code language: JavaScript (javascript)

Notice how some particulars will change on lines 1, 2, and 7, but only line 4 will be truly different (and might be expanded into many lines). So you can easily create a sheet worker template where you just supply attribute names and all the repeating stuff is created for you, leaving you to work on line 4.

Here’s an example of a google sheet for creating such sheet workers.

The linked spreadsheet gives you the code for all but that line 4 – just enter the stats on the Attributes column, separated by a space if there’s more than one (you can enter any number of stats). Copy the code down as far as you need to. Copy the Output column into your code editor window and you are ready to go.

You might have a similar template for rolltemplates, blocks of HTML, or even CSS – whatever you can imagine. The downside of this is you need to create the templating sheets then copy them back into your code. Wouldn’t it be nice if there were programs that did that for you?

3. PUG and the K-Scaffold

Pug is a program that you can write code directly into, and with it, construct the HTML, Javascript, and CSS you need for a Roll20 character sheet. It’s very capable – the downside is it’s not easy for people new to character sheet creation which, I’d argue is almost everyone who makes a sheet on Roll20. (That’s an understatement.)

To use Pug, you need to already be very competent with HTML, CSS, JS, and you need to be williing to learn a new language (the way code has to be written for PUG) and probably SCSS (a specific form of CSS that has its own restrictions). You also need to learn how to use NPM (a tool programmers are fond of), and probably set up your own local server. If all of this is gobbledigook for you, you don’t want to use Pug.

If that sounds exciting or you’re just curious, then you should check out The Sheet Author’s Journey, a series of introductory posts written by Scott M (probably the best sheet writer on Roll20) on using the K-Scaffold, a tool he wrote for for Pug and Roll20.

4. Handlebars and the handlebars program by PrimalZed

There are many programs like Pug. Handlebars is another, written specifically for HTML files (and their script block). Roll20 already uses some native handlebars code in the code for rolltemplates. There is a tool created for handlebars by Primal Zed, and you can find it on the forums (though that thread isn’t very instructional – I am working on a proper series to show how to use it).

That tool is my preferred method for sheet templating because of one key advantage: you don’t need any special skill to use it. You can write part of your code with handlebars, part with normal webdesign, and freely mix them in the same file. It’s not as capable as Pug, but it’s so, so much easier to use.

I’ll have a series of articles on writing with that handlebars tool, and its idiosyncracies (it does have some).

5. Multiversals: Templating Just For Sheet Workers

A few years ago, I observed that so much of javascript sheet workers was needless duplication so I created a templating system for them. The idea is that you supply some basics, paste the code into your script block, and the code writes the sheet workers for you.

I had already used the term Universal Sheet Workers, so I called this tool Multiversal Sheet Workers, or Multiversals for short.

The goal (as is always my goal) was to create a tool that is very easy for people who have no experience to use. Just drop the code in and go. Here’s a testimonal from Wes: That is *&#@^%@ Awesome!

You can find the first version on the roll20 forums (and an example of using it). I will make a new version, probably with another name (Marvel Multiverse turns up too much when I try to google multiversals to find my own code!).

The main drawback of this version is that it applies only to sheet workers and not HTML or CSS – that probably isn’t going to change. This tool can be used alongside handlebars, if you really want a speed up.

A Question About Speed

It has been suggested that there is a speed issue with Multiversals: this is kind of true, but also not true. Multiversals uses the exact same method for calling sheet workers as Roll20 recommends, so if there is a speed issue with multiversals, that issue lies with Roll20.

There is in fact a speed issue with Roll20. This is because of the sheet workers rely on asynchronous functions like getAttrs, setAttrs, and getSectionIDs, and those functions are at the mercy of Roll20’s servers. There are ways to write your code to minimise this issue, but this is not actually the method presented in the official documentation and multiversals follows that perfectly.

You probably need hundreds or thousands of sheet workers for this to be an issue, so it will only matter for the heaviest sheets. Again, I repeat – if this is an issue with Multiversals, it’s also an issue with Roll20.

I do have an idea for how to incorporate a speed-up for Multiversals, but it will never be an issue for the vast majority of sheets.


There is no single, correct approach to sheet templating. It is a tool that any author can use to streamlining the code writing process and you should pick the tool that works best for you (and that might be no tool at all). Ideally, you’ll use the tool to create the sheet, and then when you make the sheet available to other people, they’ll have less work to do than the original sheet creation, and won’t need to use any templating to make their tweaks.

Series NavigationThe Case Against Pug (and Sheet Templating generally) >>

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.