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:TYPEchange:TYPEchange:TYPE:PROPERTYdestroy: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:tokenchange:tokenchange:token:PROPERTYdestroy:token
|
Tokens and map graphics. |
card |
add:cardchange:cardchange:card:PROPERTYdestroy:card
|
A card played to the tabletop (a graphic). See the note below. |
dicetoken |
add:dicetokenchange:dicetokenchange:dicetoken:PROPERTYdestroy: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:abilitychange:abilitydestroy:ability
|
|
attribute |
add:attributechange:attributedestroy:attribute
|
|
campaign |
change:campaignchange:campaign:playerpageid
|
There is a single campaign object; scripts typically listen to change, not add/destroy. |
card |
add:cardchange:carddestroy:card
|
Deck card object. Also a graphic subtype — disambiguate on _type. |
character |
add:characterchange:characterdestroy:character
|
|
custfx |
add:custfxchange:custfxdestroy:custfx
|
Custom FX. |
deck |
add:deckchange:deckdestroy:deck
|
|
door |
add:doorchange:doordestroy:door
|
Latest VTT Engine. |
graphic |
add:graphicchange:graphicdestroy:graphic
|
Also fires subtype events (token, card, dicetoken). |
hand |
add:handchange:handdestroy:hand
|
|
handout |
add:handoutchange:handoutdestroy:handout
|
|
jukeboxtrack |
add:jukeboxtrackchange:jukeboxtrackdestroy:jukeboxtrack
|
|
macro |
add:macrochange:macrodestroy:macro
|
|
page |
add:pagechange:pagedestroy:page
|
Hierarchy changes also fire change:page:_placement and change:page:_path. |
pageFolder |
add:pageFolderchange:pageFolderdestroy:pageFolder
|
Mod Script Sandbox v1.5 only. |
path |
add:pathchange:pathdestroy:path
|
Classic tabletop drawings. |
pathv2 |
add:pathv2change:pathv2destroy:pathv2
|
Latest VTT Engine. |
pin |
add:pinchange:pindestroy:pin
|
Latest VTT Engine. |
player |
add:playerchange:playerdestroy:player
|
|
rollabletable |
add:rollabletablechange:rollabletabledestroy:rollabletable
|
|
tableitem |
add:tableitemchange:tableitemdestroy:tableitem
|
|
text |
add:textchange:textdestroy:text
|
|
window |
add:windowchange:windowdestroy: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.