Technical definition of Add-on Libraries: Difference between revisions
m (Standardizing capitalization of "Add-on") |
m (Added `.js` extension and clarify path info) |
||
(7 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
==Format of | ==Format of Add-on library files== | ||
Add-on libraries can be shared in a {{code|.mtlib}} file. This file is a zip file with a specific structure and content. You can import these libraries with the {{ui location|File > Add On Libraries...}} menu option. | Add-on libraries can be shared in a {{code|.mtlib}} file. This file is a zip file with a specific structure and content. You can import these libraries with the {{ui location|File > Add On Libraries...}} menu option. | ||
{| class="wikitable" | {| class="wikitable" | ||
|'''File / Directory name'''||'''Description'''|| | |'''File / Directory name'''||'''Description'''|| | ||
|- | |- | ||
|{{code|library.json}}||Configuration information for the Add-on library|| | |{{code|library.json}}||Configuration information for the Add-on library.|| | ||
|- | |- | ||
|{{code|mts_properties.json}}||Properties for macro script functions in the Add-on library|| | |{{code|mts_properties.json}}||Properties for macro script functions in the Add-on library.|| | ||
|- | |- | ||
|{{code|events.json}}||Events definition for events supported by the Add-on library|| | |{{code|events.json}}||Events definition for events supported by the Add-on library.|| | ||
|- | |- | ||
|{{code|library/}}||Contents of the Add-on library | |{{code|library/}}||Contents of the Add-on library.|| | ||
|- | |- | ||
|{{code|library/mtscript/}}||Directory containing the macro Script files for the Add-on library.|| | |{{code|library/mtscript/}}||Directory containing the macro Script files for the Add-on library.|| | ||
|- | |- | ||
|{{code|library/mtscript/public/}}||Directory containing the macro Script files that can be called via {{code|[macro(): ]}} outside of the Add-on library.|| | |{{code|library/mtscript/public/}}||Directory containing the macro Script files that can be called via {{code|[macro(): ]}} outside of the Add-on library.|| | ||
|- | |||
|{{code|library/public/}}||Contents of the library that are accessible via {{code|lib://}} URI but are not MTscript macros, such as JavaScript code or CSS or HTML.|| | |||
|} | |} | ||
== Configuration File Format: {{code|library.json}} == | == Configuration File Format: {{code|library.json}} == | ||
< | <syntaxhighlight language="javascript"> | ||
{ | { | ||
"name": "test-library", | "name": "test-library", | ||
Line 42: | Line 42: | ||
] | ] | ||
} | } | ||
</ | </syntaxhighlight> | ||
{| class="wikitable" | {| class="wikitable" | ||
|'''Name'''||'''Description'''||'''Required'''||'''Notes''' | |'''Name'''||'''Description'''||'''Required'''||'''Notes''' | ||
Line 76: | Line 76: | ||
==Events File Format: {{code|events.json}}== | ==Events File Format: {{code|events.json}}== | ||
This configuration file controls which files are executed for which events. | This configuration file controls which files are executed for which events. | ||
< | <syntaxhighlight language="javascript"> | ||
{ | { | ||
"events": [ | "events": [ | ||
{ "name": "onFirstInit", "mts": "onFirstInit" }, | { "name": "onFirstInit", "mts": "onFirstInit" }, | ||
{ "name": "onInit", "mts": "onInit"}, | { "name": "onInit", "mts": "onInit"}, | ||
{ "name": "onFirstInit", "js": "/js/onFirstInit" }, | { "name": "onFirstInit", "js": "/js/onFirstInit.js" }, | ||
{ "name": "onInit", "js": "/js/onInit"} | { "name": "onInit", "js": "/js/onInit.js"} | ||
], | ], | ||
"legacyEvents": [ | "legacyEvents": [ | ||
Line 91: | Line 91: | ||
] | ] | ||
} | } | ||
</ | </syntaxhighlight> | ||
Add-ons do not respond to the {{code|onCampaignLoad}} event. Instead they have 2 new events: | Add-ons do not respond to the {{code|onCampaignLoad}} event. Instead they have 2 new events: | ||
*{{code|onFirstInit}} - This is called only once, when the Add-on is first added to the campaign. Add the same Add-on a second time (overwriting the existing one) and it will not be called again unless the Add-on is removed first. | *{{code|onFirstInit}} - This is called only once, when the Add-on is first added to the campaign. Add the same Add-on a second time (overwriting the existing one) and it will not be called again unless the Add-on is removed first. | ||
*{{code|onInit}} - This is called every time the campaign is loaded (including after the initial {{code|onFirstInit}} event), similar to how {{code|onCampaignLoad}} is called on [[Library Token]]s. It's also called on the client when the campaign is sent to the client on the initial connection. | *{{code|onInit}} - This is called every time the campaign is loaded (including after the initial {{code|onFirstInit}} event), similar to how {{code|onCampaignLoad}} is called on [[Library Token]]s. It's also called on the client when the campaign is sent to the client on the initial connection. | ||
As of 1.13, the {{code|onFirstInit}} and {{code|onInit}} events can specify a JavaScript file to run. Unlike the MTS script, you must specify the full path to the file. If you have an entry for both MTS and JavaScript, the JavaScript script will be run first, but both will be executed. | As of 1.13, the {{code|onFirstInit}} and {{code|onInit}} events can specify a JavaScript file to run. Unlike the MTS script, you must specify the full path to the file (the example, above, shows the JavaScript code resides in the {{code|/js}} directory). If you have an entry for both MTS and JavaScript, the JavaScript script will be run first, but both will be executed. | ||
The other events must be in the {{code|legacyEvents}} section. As the name implies, these events are now considered to be legacy events. New events will be added in the future to replace these (these will not be removed). | The other events must be in the {{code|legacyEvents}} section. As the name implies, these events are now considered to be legacy events. New events will be added in the future to replace these (these will not be removed). | ||
Line 103: | Line 103: | ||
==MTScript macros== | ==MTScript macros== | ||
The {{code|library/public}} directory is only exposed via the {{code|lib://}} URI if {{code|allowsUriAccess}} is set (see the configuration file discussion, above). | The {{code|library/public/}} directory is only exposed via the {{code|lib://}} URI if {{code|allowsUriAccess}} is set (see the configuration file discussion, above). | ||
MTScript macros must all end with the file extension {{code|.mts}} to be recognized. Only MTScript files in {{code|library/mtscript/public}} can be called using {{roll|macro}} from outside of the | MTScript macros must all end with the file extension {{code|.mts}} to be recognized. Only MTScript files in {{code|library/mtscript/public/}} can be called using {{roll|macro}} from outside of the Add-on. The path of the file becomes the macro name for the {{roll|macro}} call. The namespace of the Add-on library is used for the {{code|@}} portion (the "location" of the macro). | ||
Add-on libraries support both public and private macro functions. Public macro functions must reside in the {{code|library/mtscript/public}} and can be called from anywhere (chat, other | Add-on libraries support both public and private macro functions. Public macro functions must reside in the {{code|library/mtscript/public/}} and can be called from anywhere (chat, other Add-ons, [[Library Token]]s, and macro buttons). You can call them using the following syntax: | ||
<syntaxhighlight language="mtscript"> | |||
[macro("GetTargets@lib:net.rptools.maptool.test-library")] | [macro("GetTargets@lib:net.rptools.maptool.test-library")] | ||
</ | </syntaxhighlight> | ||
{{Note|The {{code|public/}} is omitted from the macro name when calling it. You can also use subdirectories to organize your macros and would call them like {{code|[macro("somedir/macroname@lib:net.rptools.maptool.test-library")]}}.}} | The above executes the MTScript macro in the file {{code|library/mtscript/public/GetTargets.mts}}. | ||
The {{code|@this}} shorthand can also be used for calling a macro from within the same | {{Note|The {{code|public/}} is omitted from the macro name when calling it since it has to be public to be invoked. You can also use subdirectories to organize your macros and would call them like {{code|[macro("somedir/macroname@lib:net.rptools.maptool.test-library")]}}.}} | ||
The {{code|@this}} shorthand can also be used for calling a macro from within the same Add-on, similar to how it works for [[Library Token]]s. For example, {{code|[macro("mtscript2@this")]}}. | |||
Macro script files that are not in the {{code|public/}} directory can only be called from within the | Macro script files that are not in the {{code|public/}} directory can only be called from within the Add-on itself or by events. Given a library with the namespace {{code|net.mylib.addon}} with the following files: | ||
<syntaxhighlight> | |||
mtsscript/func1.mts | mtsscript/func1.mts | ||
mtsscript/public/func2.mts | mtsscript/public/func2.mts | ||
</ | </syntaxhighlight> | ||
Then: | |||
<syntaxhighlight language="mtscript"> | |||
[macro("func2@lib:net.mylib.addon")] | [macro("func2@lib:net.mylib.addon")] | ||
</ | </syntaxhighlight> | ||
can be called from anywhere, but | |||
<syntaxhighlight language="mtscript"> | |||
[macro("func1@lib:net.mylib.addon")] | [macro("func1@lib:net.mylib.addon")] | ||
</ | </syntaxhighlight> | ||
{{Note|Since the {{code|public/}} is not required, if you have two files with the same name excluding the {{code|public/}} directory component, then only the one in {{code|public/}} will be able to be executed. You will not be able to call the other macro.}} | can only be called from a macro (or via an triggered event) that is on the {{code|net.mylib.addon}} Add-on. | ||
{{Note|Since the {{code|public/}} is not required, if you have two files with the same name when excluding the {{code|public/}} directory component, then only the one in {{code|public/}} will be able to be executed. You will not be able to call the other macro.}} | |||
The above works not just with {{roll|macro}} but the other places you would expect it to as well, such as {{func|defineFunction}} for user-defined functions and macro links. | The above works not just with {{roll|macro}} but the other places you would expect it to as well, such as {{func|defineFunction}} for user-defined functions and macro links. | ||
==JavaScript macros== | |||
JavaScript code is called differently than MTscript code. | |||
A JavaScript file can be executed from outside the Add-on via the {{func|js.evalURI}} function: | |||
<syntaxhighlight language="mtscript"> | |||
[js.evalURI(context, uri)] | |||
</syntaxhighlight> | |||
This function expects a ''context'' (aka ''namespace'') and the '''URI''' that references a file containing the JavaScript code. | |||
The URI has the form {{code|lib://namespace/path}}, where ''namespace'' is the namespace of the Add-on library (as defined in its {{code|library.json}} configuration file), and ''path'' is the file path relative to {{code|library/public}}. | |||
For instance, the file {{code|library/public/test.js}} inside an Add-on library with namespace {{code|net.mylib.addon}} can be executed as: | |||
<syntaxhighlight language="mtscript"> | |||
[js.evalURI("net.mylib.addon", "lib://net.mylib.addon/test.js")]. | |||
</syntaxhighlight> | |||
Any namespace can be provided as the first parameter. If it matches a namespace for an existing Add-on, then identifier lookups (for functions and variables) will be performed within that namespace first, then the global namespace. If the namespace does not match an existing Add-on, a new empty namespace is created using the given name. This latter approach may be useful if you want to fill the namespace with new JavaScript functions dynamically, rather than putting them into the Add-on. This is likely most useful when dealing with preloading data. | |||
See [[Technical definition of Add-on Libraries#public/ Directory|public/ directory]] section below for more information on URIs. | |||
==Properties File Format: {{code|mts_properties.json}}== | ==Properties File Format: {{code|mts_properties.json}}== | ||
The {{code|mts_properties.json}} file contains property information about macro scripts. It is not required and currrently only allows you to set properties used in macro links.< | The {{code|mts_properties.json}} file contains property information about macro scripts. It is not required and currrently only allows you to set properties used in macro links. | ||
<syntaxhighlight language="json"> | |||
{ | { | ||
"properties": [ | "properties": [ | ||
Line 138: | Line 172: | ||
] | ] | ||
} | } | ||
</ | </syntaxhighlight> | ||
Where: | |||
*{{code|filename}} - is the path of the file for the MacroScript function (excluding the {{code|mtscript/}} prefix). | *{{code|filename}} - is the path of the file for the MacroScript function (excluding the {{code|mtscript/}} prefix). | ||
*{{code|autoExecute}} - determines if a macro link created for this macro will be auto executable or not. | *{{code|autoExecute}} - determines if a macro link created for this macro will be auto executable or not. | ||
*{{code|description}} - is the description that will appear in the UDF listing; unlike [[Library Token]]s, this is just a plain string and not evaluated if it contains {{code|[]}}. | *{{code|description}} - is the description that will appear in the UDF listing; unlike [[Library Token]]s, this is just a plain string and not evaluated if it contains {{code|[]}}. | ||
=={{code|public/}} Directory== | =={{code|public/}} Directory== | ||
The contents of this directory are exposed as a {{code|lib://}} URI as long as the {{code|allowsUriAccess}} is set to true in the configuration file. The public directory part of the filename is discared, for example {{code|public/myhtml.html}} -> {{code|lib://net.myaddons.addon1/myhtml.html}}. | The contents of this directory are exposed as a {{code|lib://}} URI as long as the {{code|allowsUriAccess}} is set to true in the configuration file. The public directory part of the filename is discared, for example {{code|public/myhtml.html}} -> {{code|lib://net.myaddons.addon1/myhtml.html}}. | ||
Line 152: | Line 189: | ||
The name is case sensitive, unless tokens where it is not case sensitive. The values stored do not need to be be converted to/from strings like they do with [[Library Token]]s. In many cases related to large json values, this should result in a speed improvement. The default properties list for the campain are not present for add-ons as they are not tokens, unlike [[Library Token]]s. | The name is case sensitive, unless tokens where it is not case sensitive. The values stored do not need to be be converted to/from strings like they do with [[Library Token]]s. In many cases related to large json values, this should result in a speed improvement. The default properties list for the campain are not present for add-ons as they are not tokens, unlike [[Library Token]]s. | ||
[[Add-On_Library|Parent topic page]]. | |||
[[Category:Add-on Library Functions]] |
Latest revision as of 07:28, 2 May 2024
Format of Add-on library files
Add-on libraries can be shared in a .mtlib
file. This file is a zip file with a specific structure and content. You can import these libraries with the File > Add On Libraries...
menu option.
File / Directory name | Description | |
library.json |
Configuration information for the Add-on library. | |
mts_properties.json |
Properties for macro script functions in the Add-on library. | |
events.json |
Events definition for events supported by the Add-on library. | |
library/ |
Contents of the Add-on library. | |
library/mtscript/ |
Directory containing the macro Script files for the Add-on library. | |
library/mtscript/public/ |
Directory containing the macro Script files that can be called via [macro(): ] outside of the Add-on library. |
|
library/public/ |
Contents of the library that are accessible via lib:// URI but are not MTscript macros, such as JavaScript code or CSS or HTML. |
Configuration File Format: library.json
{
"name": "test-library",
"version": "1.0.0",
"website": "www.rptools.net",
"gitUrl": "github.com/RPTools/test-library",
"authors": [ "RPTools Team" ],
"license": "GPL 3.0",
"namespace": "net.rptools.maptool.test-library",
"description": "My new test library for stuff",
"shortDescription": "test library",
"allowsUriAccess": true,
"readMeFile": "readme.md",
"licenseFile": "license.txt",
"requires": [
"net.rptools.maptool.lib.tokens"
],
"exports": [
"/somedir/",
"/someotherdir/somefile.js"
]
}
Name | Description | Required | Notes |
name |
The name of the Add-on. | Yes | - |
website |
The website for your Add-on. | No | - |
gitUrl |
The url for the git source repository. | No | - |
authors |
An array of the authors of the Add-on. | Yes | - |
license |
The name or short description of the license. | No | - |
namespace |
The namespace of the Add-on. | Yes | - |
description |
The description of the Add-on. | No | - |
shortDescription |
The short description of the Add-on. | Yes | - |
allowsUriAccess |
Should Add-on allow URI access to contents. | No | - |
readMeFile |
The path to the readme file for the Add-on. Can be plain text or GitHub-Flavored Markdown. | No | - |
licenseFile |
The path to the license file for the Add-on. | No | - |
requires |
An array of the Add-ons that are prerequisites (namespaces). | No | Added in 1.13 |
exports |
An array of directories and files that are exported to other Add-ons. | No | Added in 1.13 |
The readMeFile
and licenseFile
can be plain text, HTML, or GitHub-Flavored Markdown (GFM). These can be viewed from the Add-on Library dialog.
Events File Format: events.json
This configuration file controls which files are executed for which events.
{
"events": [
{ "name": "onFirstInit", "mts": "onFirstInit" },
{ "name": "onInit", "mts": "onInit"},
{ "name": "onFirstInit", "js": "/js/onFirstInit.js" },
{ "name": "onInit", "js": "/js/onInit.js"}
],
"legacyEvents": [
{ "name": "onInitiativeChangeRequest", "mts": "onInitiativeChangeRequest" },
{ "name": "onInitiativeChange", "mts": "onInitiativeChange" },
{ "name": "onTokenMove", "mts": "onTokenMove" },
{ "name": "onMultipleTokensMove", "mts": "onMultipleTokensMove"}
]
}
Add-ons do not respond to the onCampaignLoad
event. Instead they have 2 new events:
onFirstInit
- This is called only once, when the Add-on is first added to the campaign. Add the same Add-on a second time (overwriting the existing one) and it will not be called again unless the Add-on is removed first.
onInit
- This is called every time the campaign is loaded (including after the initialonFirstInit
event), similar to howonCampaignLoad
is called on Library Tokens. It's also called on the client when the campaign is sent to the client on the initial connection.
As of 1.13, the onFirstInit
and onInit
events can specify a JavaScript file to run. Unlike the MTS script, you must specify the full path to the file (the example, above, shows the JavaScript code resides in the /js
directory). If you have an entry for both MTS and JavaScript, the JavaScript script will be run first, but both will be executed.
The other events must be in the legacyEvents
section. As the name implies, these events are now considered to be legacy events. New events will be added in the future to replace these (these will not be removed).
Currently, only macro scripts are supported for legacyEvents
; in the future, JavaScript scripts will also be supported.
MTScript macros
The library/public/
directory is only exposed via the lib://
URI if allowsUriAccess
is set (see the configuration file discussion, above).
MTScript macros must all end with the file extension .mts
to be recognized. Only MTScript files in library/mtscript/public/
can be called using [macro():] from outside of the Add-on. The path of the file becomes the macro name for the [macro():] call. The namespace of the Add-on library is used for the @
portion (the "location" of the macro).
Add-on libraries support both public and private macro functions. Public macro functions must reside in the library/mtscript/public/
and can be called from anywhere (chat, other Add-ons, Library Tokens, and macro buttons). You can call them using the following syntax:
[macro("GetTargets@lib:net.rptools.maptool.test-library")]
The above executes the MTScript macro in the file library/mtscript/public/GetTargets.mts
.
public/
is omitted from the macro name when calling it since it has to be public to be invoked. You can also use subdirectories to organize your macros and would call them like [macro("somedir/macroname@lib:net.rptools.maptool.test-library")]
.The @this
shorthand can also be used for calling a macro from within the same Add-on, similar to how it works for Library Tokens. For example, [macro("mtscript2@this")]
.
Macro script files that are not in the public/
directory can only be called from within the Add-on itself or by events. Given a library with the namespace net.mylib.addon
with the following files:
mtsscript/func1.mts
mtsscript/public/func2.mts
Then:
[macro("func2@lib:net.mylib.addon")]
can be called from anywhere, but
[macro("func1@lib:net.mylib.addon")]
can only be called from a macro (or via an triggered event) that is on the net.mylib.addon
Add-on.
public/
is not required, if you have two files with the same name when excluding the public/
directory component, then only the one in public/
will be able to be executed. You will not be able to call the other macro.The above works not just with [macro():] but the other places you would expect it to as well, such as defineFunction() for user-defined functions and macro links.
JavaScript macros
JavaScript code is called differently than MTscript code.
A JavaScript file can be executed from outside the Add-on via the js.evalURI() function:
[js.evalURI(context, uri)]
This function expects a context (aka namespace) and the URI that references a file containing the JavaScript code.
The URI has the form lib://namespace/path
, where namespace is the namespace of the Add-on library (as defined in its library.json
configuration file), and path is the file path relative to library/public
.
For instance, the file library/public/test.js
inside an Add-on library with namespace net.mylib.addon
can be executed as:
[js.evalURI("net.mylib.addon", "lib://net.mylib.addon/test.js")].
Any namespace can be provided as the first parameter. If it matches a namespace for an existing Add-on, then identifier lookups (for functions and variables) will be performed within that namespace first, then the global namespace. If the namespace does not match an existing Add-on, a new empty namespace is created using the given name. This latter approach may be useful if you want to fill the namespace with new JavaScript functions dynamically, rather than putting them into the Add-on. This is likely most useful when dealing with preloading data.
See public/ directory section below for more information on URIs.
Properties File Format: mts_properties.json
The mts_properties.json
file contains property information about macro scripts. It is not required and currrently only allows you to set properties used in macro links.
{
"properties": [
{
"filename": "public/auto_exec.mts",
"autoExecute": true,
"description": "Auto executable macro link"
},
{
"filename": "public/myUDF.mts",
"description": "My Test UDF in a drop in lib."
}
]
}
Where:
filename
- is the path of the file for the MacroScript function (excluding themtscript/
prefix).autoExecute
- determines if a macro link created for this macro will be auto executable or not.description
- is the description that will appear in the UDF listing; unlike Library Tokens, this is just a plain string and not evaluated if it contains[]
.
public/
Directory
The contents of this directory are exposed as a lib://
URI as long as the allowsUriAccess
is set to true in the configuration file. The public directory part of the filename is discared, for example public/myhtml.html
-> lib://net.myaddons.addon1/myhtml.html
.
You can add images to this directory and use src="lib://"
in image tags in HTML. It will eventually work with audio (probably already does but I haven't tested it yet so I'm not claiming it will 🙂).
These assets will be included correctly in the campaign file when saving, so you do not need to add them to image tables or image tokens or any other tricks to make sure that they are included.
There are some differences to be aware of when using Library Token property support for add-ons.
The name is case sensitive, unless tokens where it is not case sensitive. The values stored do not need to be be converted to/from strings like they do with Library Tokens. In many cases related to large json values, this should result in a speed improvement. The default properties list for the campain are not present for add-ons as they are not tokens, unlike Library Tokens.