lib:Elevation Manual: Difference between revisions

From RPTools Wiki
Jump to navigation Jump to search
m (Correct "Drafts" category to "Draft")
mNo edit summary
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[[File:lib_elevation.png|thumb|Lib:Elevation tries to fit into the MapTool UI to add accessible elevation tools for map-making.]]
[[File:lib elevation min.png|alt=Lib:Elevation tries to fit into the MapTool UI and theme to add accessible elevation tools for map-making.|thumb|Lib:Elevation tries to fit into the MapTool UI and theme to add accessible elevation tools for map-making.]]
<h1>Welcome to Lib:Elevation!</h1>
<h1>Welcome to Lib:Elevation!</h1>
<p><strong>Download Lib:Elevation [https://github.com/melek/lib_elevation on GitHub]</strong></p>
<h2>Quick Links</h2>
<p>This library adds an elevation feature to MapTool, allowing you to&nbsp;<strong>set Visual and Movement blocking layers based on elevation</strong>&nbsp;and&nbsp;<strong>set maps, doors, and other tokens for an elevation</strong>. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.</p>
<ul>
<h2>Campaign Setup</h2>
<li><strong>[https://github.com/melek/lib_elevation Download Lib:Elevation from GitHub]</strong></li>
<li>[https://forums.rptools.net/viewtopic.php?f=8&t=29234 View the RPTools Forum Post]</li>
<li>Ask questions and discuss in the [https://discord.gg/hbn2bfn MapTool Discord] in the #map-drawing-tools channel</li>
</ul>
<h2>Introduction</h2>
<p>This library adds an elevation feature to MapTool, allowing you to <strong>set Visual and Movement blocking layers based on elevation</strong> and <strong>set maps, doors, and other tokens for an elevation</strong>. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.</p>
<p>Here are some ideas on how to use this feature:</p>
<ul>
<li>Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations. </li>
<li>Remove vision entirely to simulate flying or scrying.</li>
<li>Change the background map at different elevations for a truly &#39;vertical&#39; feeling, such as flying islands or tall, fog-filled canyons.</li>
</ul>
<h2 id="terminology">Terminology</h2>
<p>There are a few concepts in Lib:Elevation that have special names that knowing up front can help you get to using the library quickly. </p>
<p>Some of the terms are similar to other MapTool terms like layer and token, so to (hopefully) reduce confusion,
<strong>Elevations</strong> are sets</p>
<ul>
<li><strong>Token Elevation</strong>, or the elevation token property, is the vertical position of a token - how far up or down it is relative to other tokens. This is usually stored on the token as &#39;Elevaton&#39; (that is the MapTool default), and by itself is just a handy reference for players and GMs to know how high or low a token is on the map.</li>
<li><strong>Map Elevations</strong>, defined elevations, or simply elevations, are sets of data - a label, blocking layers, and linked tokens - which is shown at a particular elevation on the map. For example, a map of a maze might have &#39;Elevation 0&#39; labelled as &#39;Ground Level&#39; and block movement and sight the walls, while Elevation 20 might be labelled &#39;Flying&#39; and allow free vision and movement across the whole map. When I use the word &#39;Elevation&#39;, these special, defined elevations are usually what I mean, rather than the token property. Sometimes I may refer to elevations as &#39;layers&#39; or &#39;elevation layers&#39;, but I try to reserve that term specifically for the VBL/MBL associated with an elevation.</li>
<li><strong>Current Map Elevation</strong>, current elevation, or active elevation is the map elevation being displayed. Only one elevation is visible at a time for all players. Switching elevations means changing the current map elevation, which literally &#39;switches out&#39; which elevation you are playing on/editing. </li>
<li><strong>Faded tokens</strong> are tokens on a defined map elevation above or below the current elevation on the Token layer. These tokens will appear &#39;faded&#39; with lower opacity and placed behind tokens on the active elevation, and when they are defined will have the <code>isAbove</code> or <code>isBelow</code> state applied to it.</li>
<li><strong>Elevation Linked Tokens</strong> or <strong>Elevation Tokens</strong> refers to tokens which have their positions &#39;linked&#39; to a particular map elevation. These let you do thing slike switch the background map token, only show an NPC when they are at the same elevation as the player, hide door tokens so they don&#39;t appear at the wrong elevations. If the state is defined, these tokens will have a GM-only <code>isElevationToken</code> state applied to them to make them easier to spot for the GM.</li>
</ul>
<h2 id="campaign-setup">Campaign Setup</h2>
<p>Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.</p>
<p>Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.</p>
<ul>
<ul>
<li><strong>Drag the colored elevation macros to your Campaign/GM panels</strong>&nbsp;for quick access. The overlay UI may have some of these options, but it is nice to have the buttons handy.</li>
<li><strong>Drag the colored elevation macros to your Campaign/GM panels</strong> for quick access. The overlay UI has most of these options, but it is nice to have the buttons handy - especially in case the overlay has to be shut off for some reason. Exporting then importing these macro groups is a quick way to do this.</li>
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li>
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for &#39;*Elevation&#39;. This is a default MapTool property. If you&#39;d like to use a different property name for elevation in your campaign, you can change it in the <code>getElevationPropName</code> function.</li>
<li><strong>To show token elevation on mouse-over stat sheets</strong>, add a campaign property for 'Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the&nbsp;<code>getElevationPropName</code>&nbsp;function.</li>
<li><strong>Add elevation token states in Campaign Properties</strong>, which will be used to show when a token is at an elevation above or below the current map elevation. Add two states: <code>isAbove</code> to mark tokens on a higher defined map elevation level, and <code>isBelow</code> for tokens below the current map elevation level. Here are recommended settings for these states:<ul>
<li><strong>To show special states for token-layer tokens at different elevations</strong>, add two states:&nbsp;<code>isAbove</code>&nbsp;to mark tokens on a higher defined map elevation level, and&nbsp;<code>isBelow</code>&nbsp;for tokens below the current map elevation level. I use partly transparent, 'Yield' (down arrow) and 'Triangle' images in the 2x2 grid. Tokens will also appear faded when not on the current elevation.</li>
<li>Choose the 2x2 Grid shapes at 50% opacity </li>
<li><strong>To highlight/mark elevation tokens for GMs</strong>&nbsp;(doors, background maps, etc. set to a particular elevation), add an 'isElevationToken' state to your game and check the 'GM' and 'Mouseover' options. I use the 'Shaded' type state set to teal and 25% opacity. You can also change the property name in&nbsp;<code>getLinkedStateName</code>.</li>
<li>Use &#39;Yield&#39; (down arrow) for <code>isBelow</code></li>
<li>User &#39;Triangle&#39; (up arrow) for <code>isAbove</code></li>
<li>Tokens will also appear faded when not on the current elevation.</li>
</ul>
</ul>
<h2>Usage</h2>
</li>
<p>By default, new maps have no elevations explicitly defined and won't show the elevation list overlay for the GM. Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations.&nbsp;<strong>Changing elevations changes them for all connected players</strong>, unlike layers which the GM can freely choose between without impacting how players see the map.</p>
<li><strong>Add a GM-only state to help manage Elevation Linked Tokens</strong> such as doors, background maps, etc.. Add one state: <code>isElevationToken</code> with the following state properties:<ul>
<p>Each elevation saves a set of blocking layers (VBL and MBL) for the map, and can have tokens linked to it (<em>elevation tokens</em>) which will be hidden when a different elevation is chosen (unless that elevation also uses that elevation token). Changing between elevation layers swaps out which blocking layers are active and which elevation tokens are visible.</p>
<li>Choose the &#39;Shaded&#39; type state set to a bright color and 25% opacity.</li>
<p>On a new map without any elevations defined, the implicit default elevation is zero - but adding a different elevation will set that as the only elevation.</p>
<li>Check the &#39;GM Only&#39; option.</li>
<h3>Elevation Management Buttons</h3>
<li>Check the &#39;Mouseover&#39; option.</li>
<p>There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown:</p>
<li>You will learn more about why this state is helpful and what these linked &#39;Elevation Tokens&#39; are for.</li>
<ul>
</ul>
<li><code>Add Elev</code>&nbsp;will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like the map stamp.</li>
</li>
<li><code>&#8593;&#8593;&#8593;</code>,&nbsp;<code>&#8595;&#8595;&#8595;</code>, and&nbsp;<code>&#8593;&#8595;</code>&nbsp;switches the map elevation up, down, or to a map elevation you choose.</li>
<li><code>T&#8593;&#8595;</code>&nbsp;button switches the map elevation to the selected token.</li>
<li><code>Link Tokens</code>&nbsp;links the selected token to an elevation you select. You can use&nbsp;<code>Unlink Tokns</code>&nbsp;to undo this, or&nbsp;<code>Select Tokens</code>&nbsp;to select all the current map elevation's linked tokens.</li>
</ul>
</ul>
<h3>Token Management Buttons</h3>
<h2 id="usage">Usage</h2>
<p>These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect.</p>
<p>Lib:Elevation works by saving each elevation as a set of blocking layers (VBL and MBL) for the map, along with a list of any linked tokens which will be hidden when a different elevation is loaded. Changing between elevations swaps out which blocking layers are active and which elevation tokens are visible.</p>
<p>Please note that using these buttons usually also switches to the new elevation.</p>
<p>By default, new maps have no defined elevations and won&#39;t show the elevation list overlay for the GM. These maps are considered to be at elevation zero. You can add an elevation with the <code>Add Elev</code> button.</p>
<h2>About Elevation</h2>
<p>Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations. <strong>Changing elevations affects all connected players</strong>, unlike maps which the GM can freely preview privately without impacting which map a given player is on. If you want to check elevations on a map, it is recommended to keep the map hidden from players until you are ready for them to play on it.</p>
<p>In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to 'fill' the vertical space until the next elevation.</p>
<p>When you switch between elevations, your changes to VBL/MBL and any elevation linked tokens will be saved. Then, VBL/MBL will be cleared, elevation tokens will be hidden, and the elevation you are switching to will be loaded onto the map.</p>
<p>Here are some ideas on how to use this feature:</p>
<p>Switching elevations is done manually, or when Initiative is active, when a token takes initiative. You can also use the <code>T↑↓</code> button to match the current elevation to the selected token&#39;s elevation property.</p>
<h3 id="elevation-management-buttons">Elevation Management Buttons</h3>
<p>There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown: </p>
<ul>
<ul>
<li>Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations.</li>
<li><code>Add Elev</code> will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like a background map token.</li>
<li>Remove vision entirely to simulate flying or scrying.</li>
<li><code>↑↑↑</code>, <code>↓↓↓</code>, and <code>↑↓</code> switches the map elevation up, down, or to a map elevation you choose.</li>
<li>Change the background map at different elevations for a truly 'vertical' feeling, such as flying islands or tall, fog-filled canyons.</li>
<li><code>T↑↓</code> button switches the map elevation to match the selected token&#39;s elevation property, rounded down to the nearest defined elevation. If a token&#39;s elevation is below the lowest defined elevation, it will default to the lowest available defined map elevation.</li>
<li><code>Link Tokens</code> links the selected token to an elevation you select. You can use <code>Unlink Tokns</code> to undo this, or <code>Select Tokens</code> to select all the current map elevation&#39;s linked tokens. These options are mostly for setting maps up, but you might unlink/link a token during play if moving NPCs between levels in a house, for instance.</li>
</ul>
</ul>
<h2>Limitations</h2>
<h3 id="token-management-buttons">Token Management Buttons</h3>
<p>These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect. </p>
<p>Please note that using these buttons usually also switches to the new elevation. </p>
<h2 id="limitations">Limitations</h2>
<p>There are of course limitations given the current state of MapTool and the limits of my development time.</p>
<p>There are of course limitations given the current state of MapTool and the limits of my development time.</p>
<ul>
<ul>
Line 42: Line 70:
</ul>
</ul>
<p>For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.</p>
<p>For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.</p>
<h2>Developer notes</h2>
<h2 id="developer-notes">Developer notes</h2>
<p>Here are outlines the data structures and basic mechanism behind the library.</p>
<p>In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to &#39;fill&#39; the vertical space until the next elevation.</p>
<h3>Library Properties</h3>
<p>Here are outlines the data structures and basic mechanism behind the library. </p>
<h3 id="library-properties">Library Properties</h3>
<p>The library itself contains no properties by default. There is a library options system which lets you set library-wide options, but that feature is not currently in use. Future versions may use these options as a fallback for undefined map-level options.</p>
<p><em>Note that versions 1.0a4 and lower stored all elevation data on the library token, using map IDs as keys. This was not import/export friendly and was replaced with library reference objects stored on automatically created map elevation data tokens.</em></p>
<h3 id="map-data-token-properties">Map Data Token properties</h3>
<p>On nearly any elevation operation, a &#39;Map Elevation Data&#39; token will be automatically created and populated with library reference data. All elevation related data on the map is stored on this token. <strong>If you delete the Map Elevation Data token, you will lose all your elevation data for the map.</strong></p>
<p>Using a token in this manner allows maps to be exported and imported to other campaigns using a sufficient version of Lib:Elevation.</p>
<table>
<table>
<tr>
<tr>
<th>Property</th>
<th>Property</th>
<th>Type</th>
<th>Type</th>
<th>Purpose</th>
<th>Purpose </th>
</tr>
</tr>
<tr>
<tr>
<td>libData.elevation.elevations</td>
<td>libRefData.elevation.version</td>
<td>String</td>
<td>The version of Lib:Elevation which created the data token.</td>
</tr>
<tr>
<td>libRefData.elevation.options</td>
<td>JSON Object</td>
<td>JSON Object</td>
<td>Map IDs are keys for the current elevation. The current elevation is set when saving a map or loading a map, which happens whenever the map is switched with a UI macro. Essentially, this is almost always the 'display' elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.</td>
<td>Option names are paired with their values. If they don&#39;t exist, they are presumed to be 0. </td>
</tr>
</tr>
<tr>
<tr>
<td>libData.elevation.maps</td>
<td>libRefData.elevation.current</td>
<td>String (Integer)</td>
<td>The current elevation. This value is set when saving an elevation or loading an elevation, which happens whenever the elevation is switched with a UI macro. Essentially, this is almost always the &#39;display&#39; elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.</td>
</tr>
<tr>
<td>libRefData.elevation.layers</td>
<td>JSON Object</td>
<td>JSON Object</td>
<td>Map IDs are keys for JSON objects containing elevation data. This data structure is described below.</td>
<td>Integer IDs representing an elevation are keys for JSON objects containing elevation data. This data structure is described below.</td>
</tr>
</tr>
</table>
</table>
<h3>Data Structures</h3>
<h3 id="data-structures">Data Structures</h3>
<p>Note that Lib:Elevation uses Map and Token IDs stored on the library; this means that the library is pretty tightly coupled with a campaign. Any change to the IDs expected by the data structure will lead to undefined behavior. Importing/Exporting maps with elevation data is not currently supported.</p>
<p>Note that Lib:Elevation uses Map Data Tokens stored on each map; this means that the library is loosely coupled with a campaign, and maps can be freely exported. Token IDs should stay constant on map import, so token names and exports/imports shouldn&#39;t compromise elevation data.</p>
<h4><code>libData.elevation.maps</code></h4>
<h4 id="-librefdata-elevation-layers-"><code>libRefData.elevation.layers</code></h4>
<p>This JSON object uses Map IDs as keys to a JSON object containing elevation data, called 'Map Elevation Objects'. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:</p>
<p>This JSON object uses Map IDs as keys to a JSON object containing elevation data, called &#39;Map Elevation Objects&#39;. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:</p>
<table>
<table>
<tr>
<tr>
<th>Key</th>
<th>Key</th>
<th>Type</th>
<th>Type</th>
<th>Purpose</th>
<th>Purpose </th>
</tr>
</tr>
<tr>
<tr>
<td>label</td>
<td>label</td>
<td>String</td>
<td>String</td>
<td>A display name for the elevation. Defined elevations don't require names.</td>
<td>A display name for the elevation. Defined elevations don&#39;t require names.</td>
</tr>
</tr>
<tr>
<tr>
<td>vbl</td>
<td>vbl</td>
<td>JSON Array</td>
<td>JSON Array</td>
<td>VBL is a shape object array as returned by&nbsp;<code>getVBL()</code>.</td>
<td>VBL is a shape object array as returned by <code>getVBL()</code>.</td>
</tr>
</tr>
<tr>
<tr>
<td>mbl</td>
<td>mbl</td>
<td>JSON Array</td>
<td>JSON Array</td>
<td>MBL is a shape object array as returned by&nbsp;<code>getMBL()</code>.</td>
<td>MBL is a shape object array as returned by <code>getMBL()</code>.</td>
</tr>
</tr>
<tr>
<tr>
<td>tokens</td>
<td>tokens</td>
<td>JSON Object</td>
<td>JSON Object</td>
<td>Token ID keys containing&nbsp;<strong>token appearance</strong>&nbsp;objects. Token appearance is described below.</td>
<td>Token ID keys containing <b>token appearance</b> objects. Token appearance is described below.</td>
</tr>
</tr>
</table>
</table>
<h4>Token appearance objects</h4>
<h4 id="token-appearance-objects">Token appearance objects</h4>
<p>Token appearance are the exact parameters of how a token appears on the map. These keys are used in&nbsp;<code>getTokenAppearance()</code>&nbsp;and&nbsp;<code>setTokenAppearance()</code>. The token appearance JSON Object includes the following keys and the associated token data:</p>
<p>Token appearance are the exact parameters of how a token appears on the map. These keys are used in <code>getTokenAppearance()</code> and <code>setTokenAppearance()</code>. When  Strict Map settings, mainly Strict Token Appearance, dictate which are used. The token appearance JSON Object includes the following keys and the associated token data:</p>
<table>
<table>
<tr>
<tr>
<th>Key</th>
<th>Key</th>
<th>Data function</th>
<th>Data function</th>
</tr>
</tr>
<tr>
<tr>
<td>ID</td>
<td>ID</td>
Line 150: Line 205:
<tr>
<tr>
<td>Layout</td>
<td>Layout</td>
<td><code>getTokenLayoutProps(';', ID)</code></td>
<td><code>getTokenLayoutProps(&#39;;&#39;, ID)</code></td>
</tr>
</tr>
</table>
</table>
<h4>Token Fade Data Lists</h4>
<h4 id="token-fade-data-lists">Token Fade Data Lists</h4>
<p>Tokens on other elevations are faded with the&nbsp;<code>elevation.setTokenElevationStates</code>&nbsp;function have their opacity reduced and are assigned either the&nbsp;<code>isAbove</code>&nbsp;or&nbsp;<code>isBelow</code>&nbsp;state. Additionally, according to the&nbsp;<code>fadedTokenSight</code>&nbsp;option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.</p>
<p>Tokens on other elevations are faded with the <code>elevation.setTokenElevationStates</code> function have their opacity reduced and are assigned either the <code>isAbove</code> or <code>isBelow</code> state. Additionally, according to the <code>fadedTokenSight</code> option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.</p>
<p>When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format:&nbsp;<code>opacity, sight_type, has_sight</code></p>
<p>When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format: <code>opacity, sight_type, has_sight</code></p>
<p>This is stored by default on the token in the&nbsp;<code>libRefData.elevation.fadeData</code>&nbsp;property. This property can be changed in the&nbsp;<code>elevation.getTokenFadePropName</code>&nbsp;method.</p>
<p>This is stored by default on the token in the <code>libRefData.elevation.fadeData</code> property. This property can be changed in the <code>elevation.getTokenFadePropName</code> method.</p>
<h4>Options</h4>
<h4 id="options">Options</h4>
<p>There is a simple options API using&nbsp;<code>elevation.getOption</code>&nbsp;and&nbsp;<code>elevation.setOption</code>. This is a simple JSON object with keys (option names) and the option value, where a missing key is treated as '0'. Here are the available options:</p>
<p>There is a simple options API using <code>elevation.getMapOption</code> and <code>elevation.setMapOption</code>. This is a simple JSON object on the map&#39;s data token with keys (option names) and the option value, where a missing key is treated as &#39;0&#39;. Here is a sample of the available options, and the full list can be found in a comment on the <code>optionsDialog</code> library macro:</p>
<ul>
<table>
<li><code>fadedSightType</code>&nbsp;Determines how faded tokens have their sight settings changed when faded.
 
<ul>
<tr>
<li><code>0</code>&nbsp;- Do not change sight settings when faded.</li>
<th>Option</th>
<li><code>1</code>&nbsp;- Uncheck 'Has Sight' when faded. Prior settings are restored when unfaded.</li>
<th>Setting</th>
<li><code>sight_type</code>&nbsp;- Assigns the sight type. Does not alter the 'Has Sight' checkbox. Prior settings are retored when token is unfaded.</li>
<th>Description</th>
</ul>
</tr>
</li>
 
<li><code>useFogHack</code>&nbsp;restores fog of war each time an elevation is loaded/reloaded.
 
<ul>
<tr>
<li><code>0</code>&nbsp;- Disable fog hack.</li>
<td>fadedSightType</td>
<li><code>1</code>&nbsp;- Enable fog hack.</li>
<td>0</td>
</ul>
<td>Faded tokens (tokens on other elevations) will not have their sight settings changed in any way.</td>
</li>
</tr>
</ul>
<tr>
<h4>Sample&nbsp;<code>libData.elevation.maps</code>&nbsp;object</h4>
<td></td>
<td>1</td>
<td>&#39;Has Sight&#39; will be unchecked for all faded tokens.</td>
</tr>
<tr>
<td></td>
<td>STRING</td>
<td>A string matching a defined Sight Type will be applied to faded tokens.</td>
</tr>
<tr>
<td>heightFactor</td>
<td>N</td>
<td>This is the height multiplier the new elevation dialog uses to recommend a new elevation value. That dialog sets a fallback value of &#39;2&#39; (so for a 5 ft square, it will recommend new layers at 10 ft), but this value might also be used to determine how a future token height implementation might determine when to display a token below the current layer. </td>
</tr>
<tr>
<td>useFogHack</td>
<td>0</td>
<td>Fog of war is not affected by elevation changes.</td>
</tr>
<tr>
<td></td>
<td>1</td>
<td>Fog of war is totally restored on elevation changes, followed by immediately exposing all player token sight ranges. Use with &#39;fadedSight = 1&#39; to give a more horror-like feel to multi-story buildings. If draw/eraseFoW functions are added, this may be retired.</td>
</tr>
 
</table>
<h4 id="sample-librefdata-elevation-layers-object">Sample <code>libRefData.elevation.layers</code> object</h4>
<p>A trivial example object may look like this:</p>
<p>A trivial example object may look like this:</p>
<pre>{
<pre>{
  "A14EF2FE619B42AF828CBBAC0192131A": {
  "A14EF2FE619B42AF828CBBAC0192131A": {

Latest revision as of 23:59, 24 March 2023

Lib:Elevation tries to fit into the MapTool UI and theme to add accessible elevation tools for map-making.
Lib:Elevation tries to fit into the MapTool UI and theme to add accessible elevation tools for map-making.

Welcome to Lib:Elevation!

Quick Links

Introduction

This library adds an elevation feature to MapTool, allowing you to set Visual and Movement blocking layers based on elevation and set maps, doors, and other tokens for an elevation. Additionally, player or NPC tokens with an Elevation property can automattically view the elevation they are at when it is their initiative turn.

Here are some ideas on how to use this feature:

  • Set up outdoor maps where climbing to a higher elevation removes vision barriers from lower elevations.
  • Remove vision entirely to simulate flying or scrying.
  • Change the background map at different elevations for a truly 'vertical' feeling, such as flying islands or tall, fog-filled canyons.

Terminology

There are a few concepts in Lib:Elevation that have special names that knowing up front can help you get to using the library quickly.

Some of the terms are similar to other MapTool terms like layer and token, so to (hopefully) reduce confusion, Elevations are sets

  • Token Elevation, or the elevation token property, is the vertical position of a token - how far up or down it is relative to other tokens. This is usually stored on the token as 'Elevaton' (that is the MapTool default), and by itself is just a handy reference for players and GMs to know how high or low a token is on the map.
  • Map Elevations, defined elevations, or simply elevations, are sets of data - a label, blocking layers, and linked tokens - which is shown at a particular elevation on the map. For example, a map of a maze might have 'Elevation 0' labelled as 'Ground Level' and block movement and sight the walls, while Elevation 20 might be labelled 'Flying' and allow free vision and movement across the whole map. When I use the word 'Elevation', these special, defined elevations are usually what I mean, rather than the token property. Sometimes I may refer to elevations as 'layers' or 'elevation layers', but I try to reserve that term specifically for the VBL/MBL associated with an elevation.
  • Current Map Elevation, current elevation, or active elevation is the map elevation being displayed. Only one elevation is visible at a time for all players. Switching elevations means changing the current map elevation, which literally 'switches out' which elevation you are playing on/editing.
  • Faded tokens are tokens on a defined map elevation above or below the current elevation on the Token layer. These tokens will appear 'faded' with lower opacity and placed behind tokens on the active elevation, and when they are defined will have the isAbove or isBelow state applied to it.
  • Elevation Linked Tokens or Elevation Tokens refers to tokens which have their positions 'linked' to a particular map elevation. These let you do thing slike switch the background map token, only show an NPC when they are at the same elevation as the player, hide door tokens so they don't appear at the wrong elevations. If the state is defined, these tokens will have a GM-only isElevationToken state applied to them to make them easier to spot for the GM.

Campaign Setup

Note that the library is designed to (mostly) work without any of the items below defined, but they should be added for you to benefit from the features of the library.

  • Drag the colored elevation macros to your Campaign/GM panels for quick access. The overlay UI has most of these options, but it is nice to have the buttons handy - especially in case the overlay has to be shut off for some reason. Exporting then importing these macro groups is a quick way to do this.
  • To show token elevation on mouse-over stat sheets, add a campaign property for '*Elevation'. This is a default MapTool property. If you'd like to use a different property name for elevation in your campaign, you can change it in the getElevationPropName function.
  • Add elevation token states in Campaign Properties, which will be used to show when a token is at an elevation above or below the current map elevation. Add two states: isAbove to mark tokens on a higher defined map elevation level, and isBelow for tokens below the current map elevation level. Here are recommended settings for these states:
    • Choose the 2x2 Grid shapes at 50% opacity
    • Use 'Yield' (down arrow) for isBelow
    • User 'Triangle' (up arrow) for isAbove
    • Tokens will also appear faded when not on the current elevation.
  • Add a GM-only state to help manage Elevation Linked Tokens such as doors, background maps, etc.. Add one state: isElevationToken with the following state properties:
    • Choose the 'Shaded' type state set to a bright color and 25% opacity.
    • Check the 'GM Only' option.
    • Check the 'Mouseover' option.
    • You will learn more about why this state is helpful and what these linked 'Elevation Tokens' are for.

Usage

Lib:Elevation works by saving each elevation as a set of blocking layers (VBL and MBL) for the map, along with a list of any linked tokens which will be hidden when a different elevation is loaded. Changing between elevations swaps out which blocking layers are active and which elevation tokens are visible.

By default, new maps have no defined elevations and won't show the elevation list overlay for the GM. These maps are considered to be at elevation zero. You can add an elevation with the Add Elev button.

Once two or more elevations are present, a selection list will appear so the GM can easily switch elevations. Changing elevations affects all connected players, unlike maps which the GM can freely preview privately without impacting which map a given player is on. If you want to check elevations on a map, it is recommended to keep the map hidden from players until you are ready for them to play on it.

When you switch between elevations, your changes to VBL/MBL and any elevation linked tokens will be saved. Then, VBL/MBL will be cleared, elevation tokens will be hidden, and the elevation you are switching to will be loaded onto the map.

Switching elevations is done manually, or when Initiative is active, when a token takes initiative. You can also use the T↑↓ button to match the current elevation to the selected token's elevation property.

Elevation Management Buttons

There are some additional buttons, and you can check the tooltips of any button for more information. Here is a rundown:

  • Add Elev will add a new defined elevation. You can either start with the same MBL/VBL that the current elevation has, or start with a fresh slate. Similarly, you can copy the elevation tokens from the current elevation, hide those tokens (like you would when switching), or leave them unlinked to the new elevation but still visible - useful if you want to link only some of them, like a background map token.
  • ↑↑↑, ↓↓↓, and ↑↓ switches the map elevation up, down, or to a map elevation you choose.
  • T↑↓ button switches the map elevation to match the selected token's elevation property, rounded down to the nearest defined elevation. If a token's elevation is below the lowest defined elevation, it will default to the lowest available defined map elevation.
  • Link Tokens links the selected token to an elevation you select. You can use Unlink Tokns to undo this, or Select Tokens to select all the current map elevation's linked tokens. These options are mostly for setting maps up, but you might unlink/link a token during play if moving NPCs between levels in a house, for instance.

Token Management Buttons

These buttons simply let you change the elevation of the selected token(s). Hovering over them provides a quick view of the change they will effect.

Please note that using these buttons usually also switches to the new elevation.

Limitations

There are of course limitations given the current state of MapTool and the limits of my development time.

  • Hard fog of war is exposed for all elevations. This limits usefulness for indoor areas, as the fog for one level may greatly impact vision of another area.
  • While tokens can have their own elevation, the map can only display one elevation at a time. That means that all your players stuck in a maze will see what the Flying character is seeing on their turn.

For any questions, please go to the MapTool discord and ping Melek in #map-drawing-tools.

Developer notes

In Lib:Elevation, map elevations are special objects set at an elevation number defining walls and other visual/movement barriers at that elevation and higher (until the next defined map elevation). For instance, you may want three elevations 10 feet apart - Low ground (0), High ground (10), and Flying (20+). Each elevation should be considered to 'fill' the vertical space until the next elevation.

Here are outlines the data structures and basic mechanism behind the library.

Library Properties

The library itself contains no properties by default. There is a library options system which lets you set library-wide options, but that feature is not currently in use. Future versions may use these options as a fallback for undefined map-level options.

Note that versions 1.0a4 and lower stored all elevation data on the library token, using map IDs as keys. This was not import/export friendly and was replaced with library reference objects stored on automatically created map elevation data tokens.

Map Data Token properties

On nearly any elevation operation, a 'Map Elevation Data' token will be automatically created and populated with library reference data. All elevation related data on the map is stored on this token. If you delete the Map Elevation Data token, you will lose all your elevation data for the map.

Using a token in this manner allows maps to be exported and imported to other campaigns using a sufficient version of Lib:Elevation.

Property Type Purpose
libRefData.elevation.version String The version of Lib:Elevation which created the data token.
libRefData.elevation.options JSON Object Option names are paired with their values. If they don't exist, they are presumed to be 0.
libRefData.elevation.current String (Integer) The current elevation. This value is set when saving an elevation or loading an elevation, which happens whenever the elevation is switched with a UI macro. Essentially, this is almost always the 'display' elevation, unless you have manually used macros to load different elevation layers or hide/load elevation tokens from different elevations.
libRefData.elevation.layers JSON Object Integer IDs representing an elevation are keys for JSON objects containing elevation data. This data structure is described below.

Data Structures

Note that Lib:Elevation uses Map Data Tokens stored on each map; this means that the library is loosely coupled with a campaign, and maps can be freely exported. Token IDs should stay constant on map import, so token names and exports/imports shouldn't compromise elevation data.

libRefData.elevation.layers

This JSON object uses Map IDs as keys to a JSON object containing elevation data, called 'Map Elevation Objects'. Each Map Elevation Object contains numeric keys designating the elevation it describes. Each elevation in turn contains an object with the following optional keys - no keys are mandatory, though omitting some keys will define default behavior:

Key Type Purpose
label String A display name for the elevation. Defined elevations don't require names.
vbl JSON Array VBL is a shape object array as returned by getVBL().
mbl JSON Array MBL is a shape object array as returned by getMBL().
tokens JSON Object Token ID keys containing token appearance objects. Token appearance is described below.

Token appearance objects

Token appearance are the exact parameters of how a token appears on the map. These keys are used in getTokenAppearance() and setTokenAppearance(). When Strict Map settings, mainly Strict Token Appearance, dictate which are used. The token appearance JSON Object includes the following keys and the associated token data:

Key Data function
ID Same as Field ID
Layer getLayer(ID)
X getTokenX(1, ID)
Y getTokenY(1, ID)
Z getTokenDrawOrder(ID)
Height getTokenHeight(ID)
Width getTokenWidth(ID)
Size getSize(ID)
Facing getTokenFacing(ID)
Opacity getTokenOpacity(ID)
Visible getVisible(ID)
Shape getTokenShape(ID)
Layout getTokenLayoutProps(';', ID)

Token Fade Data Lists

Tokens on other elevations are faded with the elevation.setTokenElevationStates function have their opacity reduced and are assigned either the isAbove or isBelow state. Additionally, according to the fadedTokenSight option (see below for options documentation), sight can be disabled or changed to a different type for faded tokens.

When tokens are faded, their normal settings for opacity, sight type, and the has sight checkbox are saved in a string list in the following format: opacity, sight_type, has_sight

This is stored by default on the token in the libRefData.elevation.fadeData property. This property can be changed in the elevation.getTokenFadePropName method.

Options

There is a simple options API using elevation.getMapOption and elevation.setMapOption. This is a simple JSON object on the map's data token with keys (option names) and the option value, where a missing key is treated as '0'. Here is a sample of the available options, and the full list can be found in a comment on the optionsDialog library macro:

Option Setting Description
fadedSightType 0 Faded tokens (tokens on other elevations) will not have their sight settings changed in any way.
1 'Has Sight' will be unchecked for all faded tokens.
STRING A string matching a defined Sight Type will be applied to faded tokens.
heightFactor N This is the height multiplier the new elevation dialog uses to recommend a new elevation value. That dialog sets a fallback value of '2' (so for a 5 ft square, it will recommend new layers at 10 ft), but this value might also be used to determine how a future token height implementation might determine when to display a token below the current layer.
useFogHack 0 Fog of war is not affected by elevation changes.
1 Fog of war is totally restored on elevation changes, followed by immediately exposing all player token sight ranges. Use with 'fadedSight = 1' to give a more horror-like feel to multi-story buildings. If draw/eraseFoW functions are added, this may be retired.

Sample libRefData.elevation.layers object

A trivial example object may look like this:

{
 "A14EF2FE619B42AF828CBBAC0192131A": {
    "0": {
        "label": "Ground level",
        "vbl": "JSON Shapes Array",
        "mbl": "JSON Shapes Array",
        "tokens": {
            "BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",
            "19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"
        }
    },
    "60": {
        "label": "Cliff top",
        "vbl": "JSON Shapes Array",
        "mbl": "JSON Shapes Array",
        "tokens": {
            "BC752679AF784C7DB19EA9ACCF05A362": "JSON Token Appearance Object",
            "19EA9ACCF05A362BC752679AF784C7DB": "JSON Token Appearance Object"
         }
     }
 },
 "28CBBAC0192131AA14EF2FE619B42AF8": {
    "0": {
        "label": "Sea Level",
        "vbl": "JSON Shapes Array",
        "mbl": "JSON Shapes Array"
    },
    "10": {
        "label": "Flying",
        "vbl": "JSON Shapes Array",
         "mbl": "JSON Shapes Array"
    }
 }
}