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

Character Sheet Development/Pattern Libraries

From Roll20 Wiki

Jump to: navigation, search

Main Page: Building Character Sheets

Pattern Libararies useful for creating your own character sheets.

Pattern Libraries



Helpful Functions

//Convert Integers to be Negative
const convertIntegerNegative = number => number > 0 ? -Math.abs(number) : number

//Convert an object with negative numbers
const convertIntegersNegatives = numbers => {
  numbers => {
    for (let [key, value] of Object.entries(numbers)) {
      numbers[key] = convertIntegerNegative(value);
    return numbers

//Pass in eventinfo.triggerName
const findRepeatingField = trigger => trigger.split('_')[1]

//Pass in eventinfo.triggerName
const getReprowid = trigger => {
  const split = trigger.split('_');
  return `${split[0]}_${split[1]}_${split[2]}`

//Pass in an object keep that has the repeating section
//Example repeating_weapon_-m1czg68yzicwhfdpyys_name
const getReprowAttribute = key => {
  const getReprowid = processingFunctions.getReprowid(key)
  return key.split(`${getReprowid}_`)[1]

//Provide the function with an array of keys to find translations for 
//Example ['strength', 'agility', 'willpower']
const getTranslations = translationKeys => {
  let translations = {}
  translationKeys.forEach(key => translations[`${key}`] = getTranslationByKey(key))
  return translations

const parseInteger = string => parseInt(string) || 0

//Use for converting the result of getAttrs from strings into integers
const parseIntegers = numbers => {
  for (let [key, value] of Object.entries(numbers)) {
      numbers[key] = parseInt(value) || 0
  return numbers  

const setAttributes = (update, silent) => silent && typeof update === 'object' ? setAttrs(update, {silent:true}) : typeof update === 'object' ? setAttrs(update) : console.error(`${update} is not an object`)

//returns strength from @{strength}
const sliceAttr = attribute => attribute.slice(2, -1)

const sumIntegers = numbers => numbers.reduce((a,b) => a + b, 0)

Sheet Versioning

It can be beneficial to use a visible sheet version on a sheet, so people know when the sheet have updated. Also using sheet version will make it easier for you and others to track the state of the sheet and possible changelog.

If you have complex stat & sheetworkers in you sheet and make changes to them, it can be beneficial to add sheet versioning sheetworker that updates things for character using older version of the sheet to a new one.

An example would be to update an attribute name with a typo, to one with the correct spelling. The sheet versioning would next time a sheet is opened notice it is a older version, and then perform the sheet update transferring the attribute values of the old attribute to the new one, while it would do nothing on sheet that are already the latest version.

See also the MigrateAttributes sheetworker examples, both show a simple method for sheet versioning alongside migrating attributes to new names.

Improved Sheetworker diagnostics

TheAaronSheet contains a number of helpful sheetworker functions like simplifying repeating sections, but it also has a improved debugging settings that can help making various dev console messages more distinct.


The "Instructions"-section of the sheet.json is a bit unwieldy to fill out and structure(mix of normal Markdown-syntax, and using /n for line breaks), so it might be easier to place any larger documentation here on the Roll20 Community Wiki.

If the character sheet have several tabs or is long, the wiki could better fit more preview images of the sheet, rather than having something complicated on GitHub/the Sheet Template Preview.

Alternatively, add a in the same folder with the sheet code, and then write sheet instructions using Markdown on it.

Link to the sheet's wiki page/readme in the "Instructions" (e.g. For sheet instructions, go to [ExampleRPG](


One method of saving time with sheet dev is to use regex to find & replace more complex things in code.


Using REGEX to add title=(i.e. hover descriptions) for all attributes and roll buttons
Many sheets do not tell users the different attribute names. The easiest method is to include a title="@{attrname}" in each input/select. Buttons could also benefit from adding a title="%{buttonname}" but isn't as big of a deal.
It's possible to create a regex or some other syntax/replace command that could be run on any sheet that already doesn't have them, and add these attribute name tooltips for all attributes.
This same example could be used as a base for creating i18n attributes for sheet translations
Basic syntax to add Attribute titles:
find all: name="attr_REGEX"
replace with: name="attr_REGEX" title="@{REGEX}"
REGEX is replaced with regex commands or some other search syntax that search/accepts alphanumerals, -, _ (in essence, anything that's a valid attribute name)
Basic syntax to add Roll buttons titles:
find all: name="roll_REGEX"
replace with: name="roll_REGEX" title="%{REGEX}"
Attribute example:
find regex: name="attr_([A-Za-z0-9_-]{1,50})"
replace regex: name="attr_$1" title="@{$1}"
Buttons example:
find regex: name="roll_([A-Za-z0-9_-]{1,50})"
replace regex: name="roll_$1" title="%{$1}"
(Arbitrarily chose "50" as the max-length of possible attr names, use a larger number if you might have longer names.)

See Also