Building Character Sheets
From Roll20 Wiki
This is about a Roll20 feature exclusive to Pro-subscribers (and often to players in a Game created by a Pro-subscriber). If you'd like to use this feature, consider upgrading your account. |
Contents |
Building a Character Sheet
To build a sheet from scratch, you must have a pro account. Choose the "Custom" option in the drop-down of your Game Settings page when choosing a character sheet template. You will be presented with an editor allowing you to build the sheet. The editor has three tabs: HTML/Layout, CSS/Styling, and Preview.
HTML/Layout
HTML is used to define the fields and layout the character sheet template. You can use most of the basic HTML tags, such as p,div,textarea,input,select,img
, etc. Note that you cannot use any Javascript on your sheet template.
Creating Fields
To create a field in the sheet, use the <input type="text">
, <input type="number">
, <input type="checkbox">
, <input type="radio">
, <select>
, or <textarea>
tags. (Note: <input>
tags must have a type specified (text, number, checkbox, or radio)). For each tag, you must include a name
attribute which begins with "attr_" and defines the unique attribute name for this field. For example, <input type="text" name="attr_Strength" />
would create a text input for the "Strength" attribute. If you want the field to utilize the "max" of an attribute instead of the normal value, you can append "_max" onto the name of the field. For example, <input type="text" name="attr_Strength_max" />
. You can also use a < span >
tag to display a read-only value on your sheet. For example, < span name="attr_Strength"></ span>
. It is possible to include a span tag that has the same attribute name as an input tag, and the span tag will be updated whenever the input is modified.
Note: Attribute names are case-insensitive when checked for uniqueness. All inputs (and selects, and textareas, etc.) should have a unique attribute name.
Default Values
You can also optionally include a value
attribute on the tag, which will define the default value for the field. For example, <input type="number" name="attr_AC" value="0" />
would define an "AC" field with a default value of "0". If no default value is specified, it is an empty string ("").
Checkboxes and Radio Buttons
For checkboxes and radio buttons, you must always specify a value
attribute.
For checkboxes, if the box is checked the attribute will be set to the value of the checkbox. If it is not checked, it will be set to "0". If you would like a checkbox to be checked by default, add the "checked=true" attribute. For example, <input type='checkbox' name='attr_HasShield' value='1' checked='true' />
.
For radio buttons, if one of the radio buttons is selected, the attribute will be set to the value of that radio button. If no radio buttons are selected, the value will be an empty string. At least one of the radio buttons should have the checked="true"
attribute to set a default value. Radio buttons are the only type of field where it is permissible to have more then one field with the same "name" attribute. For example, <input type='radio' value='10' name='attr_Multiplier' /><input type='radio' value='25' name='attr_Multiplier' checked='true' />
.
Auto-Calculating Values
You can include a formula in the default value for the field, and specify the disabled="true"
attribute on the field. If you do so, the sheet will display the result of the formula instead of the formula itself. For example, <input type="number" name="attr_StrMod" value="@{Strength}/2" disabled="true" />
would create a "StrMod" field that shows half the Strength value. These auto-calculating attributes can be used in Sheet Rolls, Macros, and Abilities as normal.
Note that you can only include attributes from the current Character. You also can't include macros, abilities, or rolls...just basic math such as @{Intelligence}/2+@{Level}
. You also have access to the floor, round, and ceil functions, such as floor(@{Intelligence}/2)
.
If your auto-calculated field depends of another auto-calculated field(s), you have to add parenthesis around intermediate formula(s). Otherwise miscalculations could appear.
Example :
<input type="number" name="attr_StrMod" value="(@{Strength}/2)" disabled="true" />
<input type="number" name="attr_StrModLeveled" value="@{StrMod}+@{Level}" disabled="true" />
Note that calculations do not show up in the Preview, they only show on a character sheet in-game.
Sheet Rolls and Roll Buttons
You can include pre-defined rolls on your sheet. This is a great way to add the rolls that will be needed by the player when using the standard rolls in the game system. For example, you may want to add a "Roll Check" button next to each "Bluff", "Intimidate", etc. field on the sheet. To define a roll, just use the <button>
tag. The type
attribute should be set to "roll". The roll itself is defined in the value
attribute. You can also add a name
attribute which allows the roll to be referenced in external Macros and Abilities. A full example of a bluff check roll might look like: <button type='roll' value='/roll 1d20 + @{Bluff}' name='roll_BluffCheck'></button>
. Note that you can reference attributes/fields on the sheet using the @{AttributeName}
syntax. You could also then roll that example in other Macros or Abilities using %{CharName|BluffCheck}
. Note: The names you give your Sheet Rolls must be unique from any Ability names on your Characters if you want to reference them in Abilities or Macros. You can also just not give your Sheet Rolls names if you just want them to only be rolled by clicking the button on the Sheet itself.
Columns and Layout
While you are free to use your own CSS (see below) to layout the sheet, we do provide a few basic classes you can use to organize things into a simple column-based layout. To use them, just create a div with a class of 'sheet-3colrow', 'sheet-2colrow', or 'sheet-row'. Then inside of that div, create a div for each column with a class of 'sheet-col'. For example, to create a 3-column layout, you would could:
<div class='sheet-3colrow'> <div class='sheet-col'> <!-- Put the content for the first column here --> </div> <div class='sheet-col'> <!-- Second column --> </div> <div class='sheet-col'> <!-- Third column --> </div> </div>
Repeating Sections
Sometimes you may have a type of object where there may be one or more of them, and it's not known ahead of time how many there are. A good example of this is the Skills listing for a Character in Savage Worlds. Roll20's sheets allow you to define a template for each item in the section, and the player can then add as many of these in the listing as they need. To define a repeating section, use a <fieldset>
tag. Add a class called "repeating_sectionname" to the tag, and inside the tag put the fields that each item will have. Note that no two sections on your sheet should have the same name, and that you cannot use underscores in your sectionname. Here's an example of a Skills listing:
<h3>Skills</h3> <fieldset class="repeating_skills"> <select name="attr_dtype" class="dtype"> <option value="d4">d4</option> <option value="d6">d6</option> <option value="d8">d8</option> <option value="d10">d10</option> <option value="d12">d12</option> </select> <input type="text" name="attr_skillname" /> </fieldset>
When the sheet is displayed, Roll20 will automatically add "Add" and "Modify" buttons to allow the player to add as many of each item as needed. Each item will have its own set of fields (in the example above, each has its own "attr_dtype" and "attr_skillname").
Internally, each repeating item is stored in an attribute like so: "repeating_skills_-ABC123_dtype" or "repeating_skills_$0_skillname". The ID (the "-ABC123" part of the previous example) will never change for a repeating section row, so you can reference it in macros, abilities, and using the API. New rows that you add will be randomly assigned a new unique ID. Rows are currently ordered in the order in which they were created.
Note: All attributes in the repeating section should have a unique name globally. So if you have 'attr_Qty' in your repeating section, don't have another field called 'attr_Qty' outside of a repeating section or in another repeating section.
Security Filtering
There are a few caveats to be aware of in regards to the security filtering that Roll20 applies to your HTML:
- All classes that don't start with "attr_", "repeating_", or "roll_" will be prefixed with "sheet-".
- All images will be passed through the Roll20 image proxy to prevent security attacks. This should be largely transparent to you and shouldn't affect anything, but it's something to be aware of.
Only Use Classes, not IDs
You should not use IDs on your tags (for example, DO NOT do <input type='text' id='name' />
). Since there are multiple copies of each sheet in the DOM at once, using an ID is incorrect since IDs should only be used on unique elements.
This does mean that you cannot utilize ID-linked <label>
elements (eg, <label for="my_id">My Label Text</label>
). You can place elements inside the label to link them together (eg, <label>Label Text <input ... /></label>
), although that can come at the expense of some flexibility in your CSS.
Complete Example
Here's a complete example of a basic Savage Worlds sheet HTML layout and CSS stylesheet: Kitchen Sink example
If you're looking for a more advanced example that makes use of Sheet Workers, Compendium Integration, Roll Templates, and more, see the 5th Edition OGL Sheet by Roll20
CSS/Styling
You can use custom CSS to style the way that your sheet looks to players. You can use nearly any CSS styling that you want, including background images, colors, font sizes, etc. There are just a few caveats to note:
- All of your CSS styles will be restricted to the ".charsheet" parent class. So if you put a style called "input", the system will automatically prefix that with ".charsheet input". This shouldn't affect you in general, but it prevents you from changing any of the Roll20 application CSS outside of the character sheets.
- Note that by default, any HTML classes defined in your HTML layout which don't begin with "attr_", "roll_" or "repeating_" will be prefixed with "sheet-". So for example, if you want to style some of your input tags to be shorter than others and you define the HTML as "<input class='shortfield'>", when processing your layout it will be changed to "<input class='sheet-shortfield'>". So basically, you should probably prefix your classes in your HTML and CSS with "sheet-" to avoid confusion.
Sheet Workers Scripts
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. It is highly recommended to use these in place of Auto-Calculating Fields whenever you have values that infrequently change, such as when a Character levels up or adds a new spell or attack.
Read more at Sheet Worker Scripts
Roll Templates
Roll Templates allow you to fully customize how the rolls from your sheet appear in the chat window to all players. It's a great way to make the entire Roll20 experience match a common theme.
Read more at Roll Templates
Compendium Integration
Designating Compatibility for Your Sheet
The new Roll20 Compendium feature is a repository of information such as rules, spells, items, and monsters for select open-license gaming systems. By designating that your sheet is compatible with a Compendium, players will have direct access to that Compendium in the right sidebar during gameplay.
To designate compatibility with a Compendium, just include the Compendium's short name in the "compendium" field of your sheet.json file. For an example, see the sheet.json file of the 5th Edition OGL Sheet by Roll20 on Github.
The following Compendiums are currently available:
Name | Short Name |
---|---|
5th Edition SRD | dnd5e |
Pathfinder | pathfinder |
If you are using a Custom sheet, there is a Setting on the Game Settings page that will allow you to manually select a Compendium to use for your game.
Enabling Drag-and-Drop Functionality for Your Sheet
In addition to basic compatibility, you have the option of telling Roll20 how information from the Compendium can be included on your sheet directly. This allows players to drag-and-drop an entry from the compendium directly into your sheet, and Roll20 will fill in the values you specify. To do so, you must add the class compendium-drop-target
to the div
tag surrounding the section you want to fill in. For repeating sections, place this inside of the fieldset
tag. Then, add the accept="Attribute Name"
attribute to one or more input, select, textarea
tags. Here's a simple example which would be compatible with the Fireball entry from the 5th Edition SRD Compendium.
<fieldset class="repeating_spells"> <div class="compendium-drop-target"> <input type="text" name="attr_SpellName" accept="Name" /> <input type="text" name="attr_SpellDamage" accept="Damage" /> <select name="attr_SpellSchool" accept="School"> <option value="Abjuration">Abjuration</option> <option value="Conjuration">Conjuration</option> <option value="Divination">Divination</option> <option value="Enchantment">Enchantment</option> <option value="Evocation">Evocation</option> <option value="Illusion">Illusion</option> <option value="Necromancy">Necromancy</option> <option value="Transmutation">Transmutation</option> </select> <input type="checkbox" name="attr_SpellRitual" value="Yes" accept="Ritual"> </div> </fieldset>
- The
<Attribute Name>
inaccept="<Attribute Name>"
must match the name of an Attribute from the bottom section of the Compendium entry. Consult each individual Compendium for a listing of what Attributes are available. - For
input
andtextarea
tags, the value from the Compendium will be directly inserted. - For
input[type=checkbox]
andinput[type=radio]
tags, the box will be checked/radio selected if the value from the compendium exactly matches the value attribute from the tag. - For
select
tags, theoption
that matches the Compendium value in either the value attribute OR the text inside the option tag will be selected - You can use
accept="Content"
if you wish to receive the plaintext content from the entry (the content located above the "Attributes" header).
Note that the process of changing these values will trigger local Sheet Worker and remote API events exactly as if the user themselves had entered the data by hand. So you can also create hidden inputs to accept data from the Compendium and then process that data further using Sheet Workers if you want more control over how the data is presented. See the Spells section in the 5th Edition OGL sheet for an advanced example of this process.
Translating Character Sheets
Character sheets can be translated into other languages using the crowdsourced translation service Crowdin. Character sheet authors have a number of controls over how the sheet is translated, and how the translation is displayed. Users willing to become translators should email team@roll20.net.
Read more at Character Sheet i18n
A Small Request for Character Sheet Authors
For the most part, adding drop down menus and pre-filled options to the new digital character sheets makes them easier to use and quicker to fill out. However, there is one particular place we want to keep things free-form: the gender field. All submissions of new pull requests for any character sheet containing an area for “gender” will need to make that a blank field (as opposed to a drop down menu containing a predefined list of options). This guideline is reflective of our ongoing efforts to be inclusive in our approach to facilitating gaming-- we want the maximum amount of people to be able to game the way that provides them the most fun. In this case, taking the time to address this small programming change makes a huge difference to our community.
Preview
The preview pane updates in real-time whenever you change the HTML or CSS of your sheet to show you what that sheet will look like in-game. It's very useful for checking while your editing to make sure that the end-result is as you expect it to be.
The Preview pane applies all the same security precautions and filtering as the main Roll20 application. Be sure to right-click and Inspect Element if you are seeing strange behavior (e.g. your styles aren't being applied correctly) -- it may be that there is a security filter that is changing the name of a class or something similar.