Roll20 macros for Dungeons & Dragons 5E
I spent some time this week setting up macros in Roll20 for my D&D character and thought it'd be nice to share what I learnt. It was tough enough for me, a career software engineer, that it must be quite the struggle for a layperson.
I'll treat this post as a tutorial - if you just want the scripts, you can get them here. This is also targeted at players, and so the scripts will be hardcoded to work with a single character.
What are Roll20 macros?
Macros are little scripts to automate actions within Roll20. They can be displayed at the bottom of the game screen like so:

Some notes on the following macros
- Anywhere you see
CHARACTER_NAME
, replace it with your character's name. - These macros all assume the character sheet is the default D&D 5E sheet from Roll20.
Emote
/em *?{CHARACTER_NAME...|sighs.}*
Let's start with something basic. /em
is a chat command and will post the text after it as an "emote". The asterisks surrounding the text will make the output italic. ?{CHARACTER_NAME...|sighs.}
, or ?{<title>|<default_value>}
, is a prompt to ask us for text input. When our macro runs we will see this:

Submitting will mean we run /em *Mara tests a macro*
in the chat:

Resistances
/w @{CHARACTER_NAME|character_name} &{template:default} {{name=Resistances & Advantages}} {{Resistances=Necrotic damage}} {{Saving throw advantage=Poison, disease}} {{Skill advantage=Religion checks to recall lore about deities of death, burial practices, and the afterlife.}}
To level up, let's use a template. Templates are just a way of formatting the output in Roll20. The Roll20 D&D sheet doesn't do a good job at displaying resistances/immunities/etc., so I want a macro that posts these to the chat for quick reference.
/w
is another chat command which will "whisper" the output for us (whisper meaning only you see it). We then use &{template:default}
to specify the template we're going to use. Different templates will have different fields. In this case we have a name
field which displays a title (i.e. {{name=Resistances & Advantages}}
), and then any number of fields which we can name what we want, e.g. {{Saving throw advantage="Poison, disease"}}
. The default table essentially outputs a table of two columns and infinite rows:

Spell slots
/w @{CHARACTER_NAME|character_name}&{template:default}{{name=Spell slots}}{{Level 1=[[@{CHARACTER_NAME|lvl1_slots_total}[Total slots] - @{CHARACTER_NAME|lvl1_slots_expended}[Used slots]]]}}{{Level 2=[[@{CHARACTER_NAME|lvl2_slots_total}[Total slots] - @{CHARACTER_NAME|lvl2_slots_expended}[Used slots]]]}}{{Level 3=[[@{CHARACTER_NAME|lvl3_slots_total}[Total slots] - @{CHARACTER_NAME|lvl3_slots_expended}[Used slots]]]}}{{Level 4=[[@{CHARACTER_NAME|lvl4_slots_total}[Total slots] - @{CHARACTER_NAME|lvl4_slots_expended}[Used slots]]]}}{{Level 5=[[@{CHARACTER_NAME|lvl5_slots_total}[Total slots] - @{CHARACTER_NAME|lvl5_slots_expended}[Used slots]]]}}{{Level 6=[[@{CHARACTER_NAME|lvl6_slots_total}[Total slots] - @{CHARACTER_NAME|lvl6_slots_expended}[Used slots]]]}}{{Level 7=[[@{CHARACTER_NAME|lvl7_slots_total}[Total slots] - @{CHARACTER_NAME|lvl7_slots_expended}[Used slots]]]}}{{Level 8=[[@{CHARACTER_NAME|lvl8_slots_total}[Total slots] - @{CHARACTER_NAME|lvl8_slots_expended}[Used slots]]]}}{{Level 9=[[@{CHARACTER_NAME|lvl9_slots_total}[Total slots] - @{CHARACTER_NAME|lvl9_slots_expended}[Used slots]]]}}
In the previous example we just typed out our values, but ideally we can just reference what's already on our character sheet. This macro will output how many spell slots we have remaining per level. We have a bunch of rows that in our template that look like this:
{{Level 1=[[@{CHARACTER_NAME|lvl1_slots_total}[Total slots] - @{CHARACTER_NAME|lvl1_slots_expended}[Used slots]]]}}
Here we're introducing the [[...]]
syntax which is used to do math. Where also introducing @{CHARACTER_NAME|attribute}[label]
which can be used to reference values on our character sheet (more attributes can be found in the docs). So for example @{CHARACTER_NAME|lvl1_slots_total}[Total slots]
will return the number of slots we have at level 1 (e.g. 3) with a label "Total slots". We then subtract @{CHARACTER_NAME|lvl1_slots_expended}[Used slots]
(e.g. 1) to get our final output (e.g. 2):

Initiative
&{template:simple} {{rname=Initiative}} {{mod=Dex}} {{normal=1}} {{r1=[[d20+@{CHARACTER_NAME|initiative_bonus}[DEX] &{CHARACTER_NAME|tracker}]]}} {{charname=CHARACTER_NAME}}
Let's rolls some dice now. This macro will roll us into initiative. First off we use &{template:simple}
. This is a template specific to the D&D character sheets. The fields are specific to the template and mostly self explanatory, except for r1
: [[d20+@{CHARACTER_NAME|initiative_bonus}[DEX] &{CHARACTER_NAME|tracker}]]
. This field contains our actual roll. We take a dice roll d20
and add it to our initiative bonus (i.e. @{CHARACTER_NAME|initiative_bonus}
). This is pretty straightforward, but at the end we have something new: &{CHARACTER_NAME|tracker}
. This will take our initiative roll and set that as the value for our character in the turn tracker - your GM will thank you!

Skill checks
/w @{CHARACTER_NAME|character_name} &{template:default} {{name=Skill check}} {{Acrobatics=[@{CHARACTER_NAME|acrobatics_bonus}](~CHARACTER_NAME|acrobatics)}} {{Animal Handling=[@{CHARACTER_NAME|animal_handling_bonus}](~CHARACTER_NAME|animal_handling)}} {{Arcana=[@{CHARACTER_NAME|arcana_bonus}](~CHARACTER_NAME|arcana)}} {{Athletics=[@{CHARACTER_NAME|athletics_bonus}](~CHARACTER_NAME|athletics)}} {{Deception=[@{CHARACTER_NAME|deception_bonus}](~CHARACTER_NAME|deception)}} {{History=[@{CHARACTER_NAME|history_bonus}](~CHARACTER_NAME|history)}} {{Insight=[@{CHARACTER_NAME|insight_bonus}](~CHARACTER_NAME|insight)}} {{Intimidation=[@{CHARACTER_NAME|intimidation_bonus}](~CHARACTER_NAME|intimidation)}} {{Investigation=[@{CHARACTER_NAME|investigation_bonus}](~CHARACTER_NAME|investigation)}} {{Medicine=[@{CHARACTER_NAME|medicine_bonus}](~CHARACTER_NAME|medicine)}} {{Nature=[@{CHARACTER_NAME|nature_bonus}](~CHARACTER_NAME|nature)}} {{Perception=[@{CHARACTER_NAME|perception_bonus}](~CHARACTER_NAME|perception)}} {{Performance=[@{CHARACTER_NAME|performance_bonus}](~CHARACTER_NAME|performance)}} {{Persuasion=[@{CHARACTER_NAME|persuasion_bonus}](~CHARACTER_NAME|persuasion)}} {{Religion=[@{CHARACTER_NAME|religion_bonus}](~CHARACTER_NAME|religion)}} {{Sleight of hand=[@{CHARACTER_NAME|sleight_of_hand_bonus}](~CHARACTER_NAME|sleight_of_hand)}} {{Stealth=[@{CHARACTER_NAME|stealth_bonus}](~CHARACTER_NAME|stealth)}} {{Survival=[@{CHARACTER_NAME|survival_bonus}](~CHARACTER_NAME|survival)}}
Our next macro is mostly the same as previous ones, but introduces the concept of buttons and triggering an ability on our character sheet. It will first print a table of all our skills, with the second column being buttons with our skill modifier as the label:

Our buttons look like [@{CHARACTER_NAME|acrobatics_bonus}](~CHARACTER_NAME|acrobatics)
. [@{CHARACTER_NAME|acrobatics_bonus}]
is the label for our button, while (~CHARACTER_NAME|acrobatics)
is what happens when we click it, i.e. triggering the acrobatics
ability on our character sheet. You can check out all of the possible abilities here.
Telekinetic shove
&{template:dmg}{{savedesc=Telekinetic Shove}}{{desc=As a bonus action, you can try to telekinetically shove one creature you can see within 30 feet of you. When you do so, the target must succeed on a Strength saving throw (DC 8 + your proficiency bonus + the ability modifier of the score increased by this feat) or be moved 5 feet toward you or away from you. A creature can willingly fail this save.}}{{save=1}}{{saveattr=STR}}{{savedc=[[8+@{CHARACTER_NAME|pb}[Proficiency]+@{CHARACTER_NAME|wisdom_mod}[Wisdom]]]}}
Some abilities might not be built into the character sheet. For example my character has the "Telekinetic shove" ability. The macro for this uses the dmg
template to display fields relating to the saving throw needed. The DC though is something we need to calculate ourselves:
[[8+@{CHARACTER_NAME|pb}[Proficiency]+@{CHARACTER_NAME|wisdom_mod}[Wisdom]]]

Cantrips/Level 1 spells
/w @{CHARACTER_NAME|character_name} &{template:default} {{name=Cantrip Select}} {{Cast= [@{CHARACTER_NAME|repeating_spell-cantrip_$0_spellname}](~CHARACTER_NAME|repeating_spell-cantrip_$0_spell) [@{CHARACTER_NAME|repeating_spell-cantrip_$1_spellname}](~CHARACTER_NAME|repeating_spell-cantrip_$1_spell) [@{CHARACTER_NAME|repeating_spell-cantrip_$2_spellname}](~CHARACTER_NAME|repeating_spell-cantrip_$2_spell) [@{CHARACTER_NAME|repeating_spell-cantrip_$3_spellname}](~CHARACTER_NAME|repeating_spell-cantrip_$3_spell) [@{CHARACTER_NAME|repeating_spell-cantrip_$4_spellname}](~CHARACTER_NAME|repeating_spell-cantrip_$4_spell) }}
Spellcasting has probably been my biggest painpoint with the Roll20 D&D sheets, so I wanted a macro to speed things up a bit. This is similar to the skill check macro above - it whispers a list of cantrips my character has and buttons I can click to cast them:

The new element here is the concept of "repeating sections". Rather than reference every spell individually, I can just refer to the index in the spell book, so repeating_spell-cantrip_$0_spellname
is the name of my first cantrip, repeating_spell-cantrip_$1_spellname
is my second cantrip, and so on. This save a bunch of typing, but do note that you'll need to update the macro each time your spells change to match the number you have.
For other spell levels just replace cantrip
with 1
, 2
, etc.
Rebuke death
This last macro is an example of using one macro to call another. My character has an ability called Rebuke Death (from Kobold Press' wizard subclass the White Necromancer). It's a bit of a nuanced ability that I can't keep in my head, so I wanted to have a macro that whisper's the description:
/w @{CHARACTER_NAME|character_name}&{template:traits}@{CHARACTER_NAME|charname_output}{{name=Rebuke Death}}{{source=Class: White Necromancer}}{{description=Also starting at 2nd level, you can use an action to heal a creature you can touch. The creature regains hit points equal to your Intelligence modifier + your wizard level (minimum of 1). This feature can restore a creature to no more than half its hit point maximum. Once a creature has regained hit points from this feature, it can’t do so again until it finishes a long rest. [Send to chat](! #RebukeDeathPublic) }}
Most of that is similar to our previous macros. The one new addition is [Send to chat](! #RebukeDeathPublic)
. This will add a button to our description that, when clicked, will trigger a second macro named RebukeDeathPublic
:

The second macro looks almost the same, just this time it's sent to everyone:
&{template:traits} @{CHARACTER_NAME|charname_output} {{name=Rebuke Death}} {{source=Class: White Necromancer}} {{description=Also starting at 2nd level, you can use an action to heal a creature you can touch. The creature regains hit points equal to your Intelligence modifier + your wizard level (minimum of 1). This feature can restore a creature to no more than half its hit point maximum. Once a creature has regained hit points from this feature, it can’t do so again until it finishes a long rest. }}
Conclusion
This should hopefully introduce enough core concepts of Roll20 macros to allow you to build your own characters. I have a few more macros here that you can use, and I'd love to hear what macros you're using in your own games!