Mod Scripts: Events

There are several different types of events that you can respond to with on(event, callback). There are five event kinds: ready, change, add, destroy, and chat. Except for ready, the name includes an object type (or message for chat), and change may include a property. Each event is triggered once per object that changes. If more than one property on the object changes at the same time, only one “global” event (for example change:graphic) is triggered, plus any property-specific events you bound.

Callback Parameters

When you listen to an event, you create a function known as a callback that is executed anytime the event occurs. The callback function receives parameters that tell you what changed so you can decide what to do.

Event Arguments
ready none
change obj (Roll20 object after the change), prev (plain object of previous properties)
add obj (the new object)
destroy obj (the removed object; do not assume it still exists in the campaign)
chat msg — see Mod Scripts: Chat

obj

The object that was changed. Any changes you make to this object will also be saved to the game. So if you want to move a Graphic object to the left, you would modify the left property of obj using set.

  • obj.get("property") returns the current value for the property.
  • obj.set("property", "newvalue") sets a new value for the property. If you’re changing several properties at once you can pass an object: obj.set({left: 10, top: 20}).

prev

This is an object of the properties of the obj as they were before any changes were made due to this event. Useful for determining “how much” a property has changed.

NOTE: prev is not a Roll20 object. Access properties with bracket or dot notation: prev["bar1_value"] or prev._id. You cannot call get / set on it, and you cannot omit the underscore on read-only keys (prev.id is not prev._id).

Blob fields (bio, notes, gmnotes) in prev are not the text; they are internal identifiers. Cache previous blob values yourself if you need them.

Event Ordering

Events are fired synchronously (each function won’t start until the previous one has finished) in order from first-bound to last-bound, and also from specific property to general object. So given the following:

on("change:graphic", function1);
on("change:graphic", function2);
on("change:graphic:left", function3);

If the object’s left property changed, then the order would be function3, then function1, then function2.

If you have multiple scripts in your campaign, the scripts are loaded in the same order they appear on the Mod Scripts settings page, from left-to-right.

Note: Events are only triggered by changes made by players/the GM playing the game. Events will not be triggered by Mod Script changes made with set. So if a player moves a piece on the tabletop, you would receive a change:graphic event. If you modify the same graphic’s property in a Mod Script, there will not be a change:graphic event triggered.

ready

This event fires after all the current data for the campaign has been loaded. If you want to find a list of all objects in a campaign, or a specific object that is already in the campaign, only look for it after the ready event fires. If you bind to add events (such as add:graphic) before ready fires, you will receive add events for objects that were already present in the campaign.

Callback parameters: none

on("ready", function() {
  var tokenThatAlreadyExisted = getObj("graphic", "-ABc123");
});

Chat Events

chat:message

Triggered whenever a new chat message is received. The callback receives a msg object. Message types include general, rollresult, gmrollresult, secretrollresult, supersecretrollresult, emote, whisper, desc, direct, and api. The type name "api" is part of the message data (it is not the product name); messages beginning with ! have type === "api" and are not shown to anyone.

Callback parameters: msg

See Mod Scripts: Chat for the full msg property list and roll-result handling.

Campaign Events

The campaign object supports change:campaign and change:campaign:PROPERTY for any campaign property. The following are the ones most scripts listen for:

change:campaign:playerpageid

Fired whenever the page that the players are currently on changes.

change:campaign:turnorder

Fired whenever the turn order listing for the campaign changes.

change:campaign:initiativepage

Fired whenever the turn order is hidden or shown for a page. This may not be the same as the ID of the currently active page. If this is set to false (including if a Mod Script sets it to false), it will close the turn order for all GMs/players. Setting it to a valid page ID will open it for all GMs/players.

Object Events

Each object type supports:

  • add:TYPE
  • change:TYPE
  • change:TYPE:PROPERTY
  • destroy:TYPE

You can also bind to a specific object id: change:TYPE:ID, change:TYPE:ID:PROPERTY, and destroy:TYPE:ID.

See Mod Scripts: Objects for each type’s properties.

change:graphic

Triggered whenever a Graphic object (almost any object on the tabletop, including tokens, maps, and cards) changes.

Note: Graphic objects created by scripts will trigger this event on create.

Callback parameters: obj, prev

on("change:graphic", function(obj, prev) {
  //Do something with "obj" here. "prev" is a list of previous values.
  // Note that "obj" and "prev" are different TYPES of objects.
  // to work with obj you need to use obj.get("name");
  // to work with prev you can use prev["name"];
});

change:graphic:(property)

You can also bind to an event for each specific property on the object. So if you have a script that you want to run only when the rotation changes, you would do:

on("change:graphic:rotation", function(obj, prev) {
  //Always set rotation back to 0, so no one can rotate objects.
  obj.set("rotation", 0);
});

add:graphic

Triggered whenever a graphic object is added to the tabletop for the first time. Will also be called for existing objects when the tabletop starts up if you bind to this event outside of the ready event.

Callback parameters: obj

on("add:graphic", function(obj) {
  //Will be called for all new graphics, including ones that already existed at the start of the play session.
});
var started = false;
on("ready", function() {
  on("add:graphic", function(obj) {
    //Will only be called for new objects that get added, since existing objects have already been loaded before the ready event fires.
  });
  //You could also set a variable and ignore add events until it is true.
  started = true;
});

destroy:graphic

Triggered whenever a graphic object was removed from the tabletop.

Callback parameters: obj

Graphic subtypes

Graphics also fire events using their _subtype. Maps use the token subtype.

Subtype Events Notes
token add:token
change:token
change:token:PROPERTY
destroy:token
Tokens and map graphics.
card add:card
change:card
change:card:PROPERTY
destroy:card
A card played to the tabletop (a graphic). See the note below.
dicetoken add:dicetoken
change:dicetoken
change:dicetoken:PROPERTY
destroy:dicetoken
Dice tokens on the tabletop.

card is both a Roll20 object type and a graphic subtype, so handlers for change:card and similar events need to disambiguate on object type (for example obj.get("_type")) to be sure they are firing for the right kind of object.

All object types

Every type below supports add:TYPE, change:TYPE, change:TYPE:PROPERTY, and destroy:TYPE.

Type Example events Notes
ability add:ability
change:ability
destroy:ability
attribute add:attribute
change:attribute
destroy:attribute
campaign change:campaign
change:campaign:playerpageid
There is a single campaign object; scripts typically listen to change, not add/destroy.
card add:card
change:card
destroy:card
Deck card object. Also a graphic subtype — disambiguate on _type.
character add:character
change:character
destroy:character
custfx add:custfx
change:custfx
destroy:custfx
Custom FX.
deck add:deck
change:deck
destroy:deck
door add:door
change:door
destroy:door
Latest VTT Engine.
graphic add:graphic
change:graphic
destroy:graphic
Also fires subtype events (token, card, dicetoken).
hand add:hand
change:hand
destroy:hand
handout add:handout
change:handout
destroy:handout
jukeboxtrack add:jukeboxtrack
change:jukeboxtrack
destroy:jukeboxtrack
macro add:macro
change:macro
destroy:macro
page add:page
change:page
destroy:page
Hierarchy changes also fire change:page:_placement and change:page:_path.
pageFolder add:pageFolder
change:pageFolder
destroy:pageFolder
Mod Script Sandbox v1.5 only.
path add:path
change:path
destroy:path
Classic tabletop drawings.
pathv2 add:pathv2
change:pathv2
destroy:pathv2
Latest VTT Engine.
pin add:pin
change:pin
destroy:pin
Latest VTT Engine.
player add:player
change:player
destroy:player
rollabletable add:rollabletable
change:rollabletable
destroy:rollabletable
tableitem add:tableitem
change:tableitem
destroy:tableitem
text add:text
change:text
destroy:text
window add:window
change:window
destroy:window
Latest VTT Engine.

Mod Script Sandbox v1.5 only. pageFolder objects have add:pageFolder, change:pageFolder, destroy:pageFolder, and property events such as change:pageFolder:name. Pages also fire change:page:_placement and change:page:_path when the page menu hierarchy changes.

Jumpgate / Latest VTT Engine object types (pathv2, pin, window, door) are VTT-engine features, not sandbox-version features. A v1.0 game on the Latest VTT Engine still has those object types and their events.

Was this article helpful?
12 out of 16 found this helpful