Difference between revisions of "Mod:Development"
From Roll20 Wiki
(Change category so it sorts this under A for API instead of I for Introduction) |
Andreas J. (Talk | contribs) m (link to Mod Scripts Major Update 2024) |
||
(28 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{revdate}}{{HCbox| {{hc|articles/360037256714-API Here}} }} | ||
+ | {{pro only}} | ||
+ | {{mod}} | ||
{{apibox}} | {{apibox}} | ||
+ | '''Go to the [[Mod:Use Guide]]-page for how to use/install existing APIs.''' This is an introduction to creating & modifying API Scripts. | ||
− | + | =Mod Script Creation - Introduction= | |
+ | The '''Roll20 API''' provides a powerful way to customize and enhance your game. You write scripts (little pieces of code) that tell Roll20 what to do during gameplay (for instance, move a piece, add a status marker to a [[token]], roll a [[dice]], create [[handout]], edit [[Character#Attributes|character stats]], [[Jukebox|play music]], and much more). It's simple and straightforward to get started, but the possibilities are endless. | ||
+ | ==What do I need to get started?== | ||
− | + | Scripts for the Roll20 API are written in '''[[JavaScript]]'''. You only need a basic understanding of the language to get started, but if you want to learn more about JavaScript, this [http://www.codecademy.com/tracks/javascript Codecademy] course can help teach you. | |
− | ''' | + | * '''{{fpl|10419353/ Aaron's tips on getting started - API Development}}''' - (Sept. 2021) |
+ | * '''Recommended browser Plugin: [[Roll20 Autouploader]]''' -- [[Browser#Plugins|browser plugin]] that can autoupload & update your API script in roll20, so you don't have to do it manually. Also can do the same for char sheets in [[Sheet Sandbox]]. | ||
+ | * [[Mod Scripts Major Update 2024]] | ||
+ | * [https://app.roll20.net/forum/permalink/11029363/ Bugs/Missing Feature Parity/Desired Features for Mods] Aug 2022 thread by [[Aaron]] | ||
− | + | ==How does it work?== | |
+ | You write scripts that listen to events that happen during the game. Scripts can check to make sure that rules are followed, change properties on objects and tokens, and even provide custom chat commands. The scripts you write run across the entire game, and affect things the GM does as well as all the players. Advanced scripts can also run independently, performing automatic actions such as moving a token on a patrol route or nudging players when their turn is taking too long. | ||
− | ''' | + | See '''[[API:Use Guide|Use Guide]]''' for installing & using existing APIs. |
+ | ==Where can I find pre-made scripts?== | ||
− | + | The API Script community is fairly active with members creating and discussing scripts all the time. There are 3 basic places to look for new scripts: | |
+ | * '''The {{repo|Roll20/roll20-api-scripts Official Roll20 API Script Repo}} on Github.''' This is where you'll find the current version of scripts that authors have submitted for inclusion in the repo. | ||
+ | * '''The {{forum|category/46806 Roll20 API Scripts}}''' This subforum is where scripts tend to show up first and where discussion happens about scripts that are being written or need changes. This is also where you can post and ask for help from the community in creating a script you've thought of, or finding a script to fill a need. | ||
+ | * '''The [[API:Script_Index|Wiki's API Script Index]].''' This is a good source of information about popular scripts, but it's not too well maintained nor does it describe all APIs that currently are available in the one-click menu.. However, if you'd like to document some scripts you find useful, their authors would certainly appreciate it! | ||
+ | ** [[API:Short Community Scripts]] contains some APIs that aren't in the install menu | ||
+ | |||
+ | ==Types of scripts== | ||
+ | {{NavMacroDocs}} | ||
+ | Examples of creating APIs. See [[API:Index]] for list of APIs to install. | ||
+ | ===Reactive Scripts: Listen to Events, Modify Objects=== | ||
+ | The first (and most simple type) of API usage is to react to changes on the tabletop, and then respond by making additional changes to the changed objects. This type of script is composed of a number of functions which listen to events that happen during the game. Then it will modify objects that are passed during those events, which will change what happens on the tabletop. | ||
+ | |||
+ | The most basic script which would simply move any piece which moved an additional 5 feet (assuming default page settings) would be: | ||
+ | |||
+ | <pre data-language="javascript"> | ||
+ | on("change:graphic", function(obj) { | ||
+ | obj.set({ | ||
+ | left: obj.get("left") + 70 | ||
+ | }); | ||
+ | }); | ||
+ | </pre> | ||
+ | |||
+ | As you can see, we created a simple function using on which will be executed anytime the <code>change:graphic</code> event is heard. The function is passed the graphic object <code>obj</code>. To make a change, we just modify <code>obj</code> using the <code>set</code> function -- whatever properties we change will be detected and changed on the tabletop. | ||
+ | |||
+ | '''Important Note:''' You must use <code>set</code> and <code>get</code> to set and get current values on objects or your changes will not be saved. (See below for a listing of object types and their properties, as well as a listing of all events and what arguments each event is passed.) | ||
+ | |||
+ | ====A Note on Utility Functions==== | ||
+ | Of course, the previous example isn't incredibly helpful because it always adds 70 pixels to the location of the [[token]]. But what if the user has changed their scale so that 5ft is 140 pixels? The Roll20 API provides several handy utility functions to help with this (and other) common scenarios. Let's modify our previous example to use the <code>distanceToPixelsfunction</code>, which will tell us how many pixels "five feet" (or inches, or meters, or whatever other distance type has been set) on the tabletop is. | ||
+ | |||
+ | <pre data-language="javascript"> | ||
+ | on("change:graphic", function(obj) { | ||
+ | obj.set({ | ||
+ | left: obj.get("left") + distanceToPixels(5) | ||
+ | }); | ||
+ | }) | ||
+ | </pre> | ||
+ | |||
+ | Now if the current page is setup to use the default grid sizing, <code>distanceToPixels(5);</code> will still return 70 pixels, but if the page is setup to have a scale twice the size of normal, it would return 140. | ||
+ | |||
+ | It's always a good idea to use utility functions whenever they're available to help keep your script from breaking if the settings of a page or a token change. | ||
+ | |||
+ | ===Proactive Scripts: Do Things Without User Intervention=== | ||
+ | In addition to reacting to user events, you can also do things with the API automatically that aren't tied to a specific event from the [[players]]. For example, let's have a [[token]] that patrols back and forth on the map. | ||
+ | |||
+ | ''Note'': Although this type of script is not dependent on user interaction, the API scripts for your game will still only run when at least one person is connected to your game. | ||
+ | |||
+ | <pre style="overflow:auto;white-space:pre-wrap;" data-language="javascript"> | ||
+ | on("ready", function() { | ||
+ | //Wait until the ready event fires so we know the game is completely loaded. | ||
+ | //Get a reference to our patrolling token. | ||
+ | var patroltoken = findObjs({_type: "graphic", name: "Guard A"})[0]; //We know there is a token in the Game called "Guard A". | ||
+ | var direction = -1*distanceToPixels(5); //Walk left 70 pixels. | ||
+ | var stepstaken = 0; //How many steps have we walked in the current direction? | ||
+ | setInterval(function() { | ||
+ | if(stepstaken > 3) { | ||
+ | //Switch directions! | ||
+ | direction = direction * -1; //will "flip" the direction we're walking | ||
+ | stepstaken = 0; //reset steps back to 0. | ||
+ | } | ||
+ | patroltoken.set("left", patroltoken.get("left") + direction); //walk! | ||
+ | stepstaken++; | ||
+ | }, 5000); //take an action every 5 seconds | ||
+ | }); | ||
+ | </pre> | ||
+ | |||
+ | ===A Treatise on Asynchronous Functions=== | ||
+ | |||
+ | An asynchronous function is one that returns the thread of control to the calling scope immediately and performs some duty in the background. Here's a very simple and easy to understand example which you can paste in an API scripts tab: | ||
+ | |||
+ | <pre style="overflow:auto;white-space:pre-wrap;" data-language="javascript"> | ||
+ | on('ready',function(){ | ||
+ | log('Parent Scope - Before call to asynchronous function.'); | ||
+ | |||
+ | setTimeout(function(){ | ||
+ | log('Asynchronous Function Scope - Doing the Asynchronous function work.'); | ||
+ | },10 /* 10 milliseconds */); | ||
+ | |||
+ | log('Parent Scope - after call to asynchronous function.'); | ||
+ | }); | ||
+ | </pre> | ||
+ | |||
+ | In the API log, you'll see something like this: | ||
+ | <pre style="background-color:#333; color: #E6DB74;"> | ||
+ | "Parent Scope - Before call to asynchronous function." | ||
+ | "Parent Scope - after call to asynchronous function." | ||
+ | "Asynchronous Function Scope - Doing the Asynchronous function work." | ||
+ | </pre> | ||
+ | |||
+ | Looking at that code, you think "Of course it will happen later, you told it to run in 10 milliseconds, duh?". Here is a less obvious example that will have the same log messages: | ||
+ | |||
+ | <pre style="overflow:auto;white-space:pre-wrap;" data-language="javascript"> | ||
+ | on('ready',function(){ | ||
+ | log('Parent Scope - Before call to asynchronous function.'); | ||
+ | |||
+ | sendChat('Async Function','Evaluate this: [[1d6]]',function(msg){ | ||
+ | log('Asynchronous Function Scope - Doing the Asynchronous function work.'); | ||
+ | }); | ||
+ | |||
+ | log('Parent Scope - after call to asynchronous function.'); | ||
+ | }); | ||
+ | </pre> | ||
+ | |||
+ | Asynchronous functions are necessary to prevent the API from hanging all the time. If every dice roll was handled synchronously, the API would be super sluggish and unresponsive. Almost any function you see that takes a callback is asynchronous. (Exception for some of the <code>_.map</code>, <code>_.reduce</code>, etc functions, these are examples of functional programming in contrast to the procedural programming most people are used to.) | ||
+ | |||
+ | |||
+ | ==Contributing Mod Scripts to the Community== | ||
+ | If you create a script that you'd like to offer to the rest of the Roll20 community, you can submit it to be included in the [https://github.com/Roll20/roll20-api-scripts Official Roll20 API Script Repo]. Having your script approved by the Roll20 staff and included in the repository will unlock the <div style="width: auto; display: inline-block; margin-left: 5px; position: relative; top: -2px; background-color: #21c0d0; padding: .2em .5em .2em; font-size: 14px; min-width: 10px; font-weight: bold; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: 10px; box-sizing: border-box; font-family: Helvetica,Arial,sans-serif;">API Scripter</div> forum tag for your account as will allow you to advertise via Patreon or Patreon-like sites (see below for more info). | ||
+ | |||
+ | To find out what you need to do to correctly submit your script to the repository, check: | ||
+ | * [https://github.com/Roll20/roll20-api-scripts#contributing Roll20 API Scripts README#contributing] | ||
+ | * [https://github.com/Roll20/roll20-api-scripts/tree/master/_Example%20Script%20-%20Check%20for%20formatting%20details Example API Script] | ||
+ | |||
+ | Guides for how to submit content to Github: | ||
+ | * [[Github|Beginners guide to GitHub]] | ||
+ | * [[Short Git Guide]] - how to do most things on the Git command line | ||
+ | |||
+ | ===script.json=== | ||
+ | {{:script.json}} | ||
− | + | ===Linking to Patreon/Tipeee on the Roll20 Forums=== | |
+ | Linking to Patreon or Tipeee on the Roll20 Forums are only permitted for pre-approved community members who have contributing either Character Sheets or API Scripts. If you wish to solicit users directly for funding you may do so privately, but no such links are permitted in a public forum without any contributed material.<br /> | ||
− | + | ==Mod Meta Libraries== | |
+ | * Check the [[API:Script_Index#Library.2FMeta_Scripts|Library & Meta Scripts]] APIs made to interact or support other APIs, which can be relied on instead of writing everything yourself. | ||
+ | * [https://github.com/onyxring/Roll20OralOrcs Roll20 Oral Orcs] framework to simplify API writing for Roll20 | ||
− | + | =Related Pages= | |
+ | * [[Roll20 Autouploader]] -- browser plugin that can autoupload & update your Mod script in roll20, so you don't have to do it manually. | ||
+ | * '''{{macro guide}}''' | ||
+ | ** {{Text Chat}} - where the roll results appear, & info on the common chat commands | ||
+ | ** [[Dice Reference]] - Comprehensive list of how the Roll20 dice-rolling syntax works, and list the features available | ||
+ | ** [[Macros]] - How to create macros, and other info on how the Roll20 {{Text Chat}} works, like referencing stats on character sheets, roll queries, nesting macros & initiative | ||
+ | *** [[Reusing Rolls]] | ||
+ | ** [[Roll Templates]] - a method of formatting roll results in the chat, with some extra functions | ||
+ | ** [[Mod]]''(Pro Only)'' - Mod commands can be used in the {{Text Chat}} | ||
− | [[Category:API | + | [[Category:API]] |
+ | [[Category:API Development]] | ||
+ | [[Category:Docs]] |
Latest revision as of 11:42, 3 May 2024
Page Updated: 2024-05-03 |
Attention: This page is community-maintained. For the official Roll20 version of this article, see the Help Center for assistance: Here .
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. |
This is related to Roll20 Mods, which require Pro info from the game's creator.(formerly known as API "Scripts") Main Page: Mod:Use Guide |
Roll20 Mod
Use Mods
- Use & Install
- Mod:Script Index & Suggestions
- Short Community Scripts
- Meta Scripts
- User Documentation
- Mod Scripts(Forum)
- Mod Update 2024🆕
- Macro Guide
Mod Development
- Mod:Development
- Guide to Mod framework
- Contributing
- Guide to GitHub
- Category:API
Reference
- Objects
- Events
- Chat Events & Functions
- Utility Functions
- Function
- Roll20 object
- Token Markers
- Sandbox Model
- Debugging
Cookbook
Go to the Mod:Use Guide-page for how to use/install existing APIs. This is an introduction to creating & modifying API Scripts.
Contents |
[edit] Mod Script Creation - Introduction
The Roll20 API provides a powerful way to customize and enhance your game. You write scripts (little pieces of code) that tell Roll20 what to do during gameplay (for instance, move a piece, add a status marker to a token, roll a dice, create handout, edit character stats, play music, and much more). It's simple and straightforward to get started, but the possibilities are endless.
[edit] What do I need to get started?
Scripts for the Roll20 API are written in JavaScript. You only need a basic understanding of the language to get started, but if you want to learn more about JavaScript, this Codecademy course can help teach you.
- Aaron's tips on getting started - API Development(Forum) - (Sept. 2021)
- Recommended browser Plugin: Roll20 Autouploader -- browser plugin that can autoupload & update your API script in roll20, so you don't have to do it manually. Also can do the same for char sheets in Sheet Sandbox.
- Mod Scripts Major Update 2024
- Bugs/Missing Feature Parity/Desired Features for Mods Aug 2022 thread by Aaron
[edit] How does it work?
You write scripts that listen to events that happen during the game. Scripts can check to make sure that rules are followed, change properties on objects and tokens, and even provide custom chat commands. The scripts you write run across the entire game, and affect things the GM does as well as all the players. Advanced scripts can also run independently, performing automatic actions such as moving a token on a patrol route or nudging players when their turn is taking too long.
See Use Guide for installing & using existing APIs.
[edit] Where can I find pre-made scripts?
The API Script community is fairly active with members creating and discussing scripts all the time. There are 3 basic places to look for new scripts:
- The Official Roll20 API Script Repo on Github. This is where you'll find the current version of scripts that authors have submitted for inclusion in the repo.
- The Roll20 API Scripts(Forum) This subforum is where scripts tend to show up first and where discussion happens about scripts that are being written or need changes. This is also where you can post and ask for help from the community in creating a script you've thought of, or finding a script to fill a need.
- The Wiki's API Script Index. This is a good source of information about popular scripts, but it's not too well maintained nor does it describe all APIs that currently are available in the one-click menu.. However, if you'd like to document some scripts you find useful, their authors would certainly appreciate it!
- API:Short Community Scripts contains some APIs that aren't in the install menu
[edit] Types of scripts
Macro Creation
- Complete Guide to Macros & Rolls
- q Text Chat
- Dice Reference
- Order of Operations
- Macros
- Token Reference
- Character Reference
- Roll Templates
- Roll Table
Advanced
- Formatting
- HTML Replacement
- Chat Menus
- Hidden Rolls
- Advanced Macro Tips
- API Commands
- Char Sheet Creation
- External tools
Misc.
Examples of creating APIs. See API:Index for list of APIs to install.
[edit] Reactive Scripts: Listen to Events, Modify Objects
The first (and most simple type) of API usage is to react to changes on the tabletop, and then respond by making additional changes to the changed objects. This type of script is composed of a number of functions which listen to events that happen during the game. Then it will modify objects that are passed during those events, which will change what happens on the tabletop.
The most basic script which would simply move any piece which moved an additional 5 feet (assuming default page settings) would be:
on("change:graphic", function(obj) { obj.set({ left: obj.get("left") + 70 }); });
As you can see, we created a simple function using on which will be executed anytime the change:graphic
event is heard. The function is passed the graphic object obj
. To make a change, we just modify obj
using the set
function -- whatever properties we change will be detected and changed on the tabletop.
Important Note: You must use set
and get
to set and get current values on objects or your changes will not be saved. (See below for a listing of object types and their properties, as well as a listing of all events and what arguments each event is passed.)
[edit] A Note on Utility Functions
Of course, the previous example isn't incredibly helpful because it always adds 70 pixels to the location of the token. But what if the user has changed their scale so that 5ft is 140 pixels? The Roll20 API provides several handy utility functions to help with this (and other) common scenarios. Let's modify our previous example to use the distanceToPixelsfunction
, which will tell us how many pixels "five feet" (or inches, or meters, or whatever other distance type has been set) on the tabletop is.
on("change:graphic", function(obj) { obj.set({ left: obj.get("left") + distanceToPixels(5) }); })
Now if the current page is setup to use the default grid sizing, distanceToPixels(5);
will still return 70 pixels, but if the page is setup to have a scale twice the size of normal, it would return 140.
It's always a good idea to use utility functions whenever they're available to help keep your script from breaking if the settings of a page or a token change.
[edit] Proactive Scripts: Do Things Without User Intervention
In addition to reacting to user events, you can also do things with the API automatically that aren't tied to a specific event from the players. For example, let's have a token that patrols back and forth on the map.
Note: Although this type of script is not dependent on user interaction, the API scripts for your game will still only run when at least one person is connected to your game.
on("ready", function() { //Wait until the ready event fires so we know the game is completely loaded. //Get a reference to our patrolling token. var patroltoken = findObjs({_type: "graphic", name: "Guard A"})[0]; //We know there is a token in the Game called "Guard A". var direction = -1*distanceToPixels(5); //Walk left 70 pixels. var stepstaken = 0; //How many steps have we walked in the current direction? setInterval(function() { if(stepstaken > 3) { //Switch directions! direction = direction * -1; //will "flip" the direction we're walking stepstaken = 0; //reset steps back to 0. } patroltoken.set("left", patroltoken.get("left") + direction); //walk! stepstaken++; }, 5000); //take an action every 5 seconds });
[edit] A Treatise on Asynchronous Functions
An asynchronous function is one that returns the thread of control to the calling scope immediately and performs some duty in the background. Here's a very simple and easy to understand example which you can paste in an API scripts tab:
on('ready',function(){ log('Parent Scope - Before call to asynchronous function.'); setTimeout(function(){ log('Asynchronous Function Scope - Doing the Asynchronous function work.'); },10 /* 10 milliseconds */); log('Parent Scope - after call to asynchronous function.'); });
In the API log, you'll see something like this:
"Parent Scope - Before call to asynchronous function." "Parent Scope - after call to asynchronous function." "Asynchronous Function Scope - Doing the Asynchronous function work."
Looking at that code, you think "Of course it will happen later, you told it to run in 10 milliseconds, duh?". Here is a less obvious example that will have the same log messages:
on('ready',function(){ log('Parent Scope - Before call to asynchronous function.'); sendChat('Async Function','Evaluate this: [[1d6]]',function(msg){ log('Asynchronous Function Scope - Doing the Asynchronous function work.'); }); log('Parent Scope - after call to asynchronous function.'); });
Asynchronous functions are necessary to prevent the API from hanging all the time. If every dice roll was handled synchronously, the API would be super sluggish and unresponsive. Almost any function you see that takes a callback is asynchronous. (Exception for some of the _.map
, _.reduce
, etc functions, these are examples of functional programming in contrast to the procedural programming most people are used to.)
[edit] Contributing Mod Scripts to the Community
If you create a script that you'd like to offer to the rest of the Roll20 community, you can submit it to be included in the Official Roll20 API Script Repo. Having your script approved by the Roll20 staff and included in the repository will unlock theTo find out what you need to do to correctly submit your script to the repository, check:
Guides for how to submit content to Github:
- Beginners guide to GitHub
- Short Git Guide - how to do most things on the Git command line
[edit] script.json
Details: Creating a script.json File
Some extra details:
- "roll20userid" - add your id here to get the "API Scripter"-forum flair - find your roll20userid
[edit] Description
"description"
is the text displayed on the API Install page. It's written in markdown, with a few quirks. You can have markdown hyperlinks
- See sheet.json#Instructions for formatting tips
- With some changes, you can use Sheet Sandbox to test how the "description" will look like in the One-click menu. Good for checking it's readable
[edit] Patreon and Tipeee Link
For API script authors that are contributing to the Roll20 Roll20 API repo, they are approved to advertise via subscription/donation service sites: Patreon and Tipeee. Roll20 is not responsible for any payment transactions and cannot enforce any private arrangements.
In order to qualify, an API script author must first have their script contribution approved by the Roll20 staff and included into the Roll20 API Script Repo.
You will want to include your Patreon or Tipeee account information in the script.json
file that should be included with your script submission on GitHub.
The json file should have one of these fields added to it if you wish to advertise with Patreon or Tipeee:
patreon:
Place the URL for a Patreon campaign here, and it will appear under your script's description when selected. (e.g."https://www.patreon.com/<name>"
)
tipeee:
Place the URL for a Tipeee here, and it will appear under your script's description when selected. (e.g."https://www.tipeee.com/<name>"
)
For more information, see github.com/Roll20/roll20-api-scripts#contributing
[edit] Linking to Patreon/Tipeee on the Roll20 Forums
Linking to Patreon or Tipeee on the Roll20 Forums are only permitted for pre-approved community members who have contributing either Character Sheets or API Scripts. If you wish to solicit users directly for funding you may do so privately, but no such links are permitted in a public forum without any contributed material.
[edit] Mod Meta Libraries
- Check the Library & Meta Scripts APIs made to interact or support other APIs, which can be relied on instead of writing everything yourself.
- Roll20 Oral Orcs framework to simplify API writing for Roll20
[edit] Related Pages
- Roll20 Autouploader -- browser plugin that can autoupload & update your Mod script in roll20, so you don't have to do it manually.
- Complete Guide to Macros & Rolls
- q Text Chat - where the roll results appear, & info on the common chat commands
- Dice Reference - Comprehensive list of how the Roll20 dice-rolling syntax works, and list the features available
- Macros - How to create macros, and other info on how the Roll20 q Text Chat works, like referencing stats on character sheets, roll queries, nesting macros & initiative
- Roll Templates - a method of formatting roll results in the chat, with some extra functions
- Mod(Pro Only) - Mod commands can be used in the q Text Chat