I've been meaning to write a metascript plugin that would calculate range for you (right in the command line of another script), however you can do it with existing metascript tools. The equation is a bit more than what GiGs shared, at least for Euclidean, since you'd first have to determine the distance along the ground between the tokens (solving one pythagorean formula), before you could use that and the difference in altitudes between the 2 tokens for a second pythagorean formula. Here's how to do that... You can get all the values you need using Fetch... like the blue markers: @(selected.status.blue?all) ...or the tops: @(selected.top) ...etc. Now, since we'll be figuring between two tokens, we'll probably need to target one of them, meaning that we won't have our typical array of "selected" tokens (a quirk of Roll20 message construction). So we'll use a ZeroFrame {&global} structure to just tag our selected and targeted token ids so that we can use them throughout the macro. Here is a proof of concept that will kick out a roll template with the information tagged and organized for you to see it working: !&{template:default}{{name=Range Test}}{{Lefts=@(seltoken.left) - @(tartoken.left) = [\][\]@(seltoken.left)-@(tartoken.left)\]\]}}{{Tops=@(seltoken.top) - @(tartoken.top) = [\][\]@(seltoken.top)-@(tartoken.top)\]\]}}{{Ground Distance=grdDistance}}{{Altitude Difference=altDiff}}{{Actual Distance=[\\][\\]round((grdDistance**2 + altDiff**2)**0.5)\\]\\]}}{&simple}{&global ([seltoken]@{selected|token_id})([tartoken]@{target|Target|token_id})}{\&global ([grdDistance] [\][\]round(((@(seltoken.left)-@(tartoken.left))**2 + (@(seltoken.top)-@(tartoken.top))**2)**0.5)\]\]) ([altDiff] [\][\]@(seltoken.status.blue?all[0])-@(tartoken.status.blue?all[0])\]\])} REQUIRED SCRIPTS: ZeroFrame (pending 1-click release this week), Fetch (pending 1-click release this week) Now, if you only wanted the range as a number (rather than all the template information), that would be this: {&global ([seltoken]@{selected|token_id})([tartoken]@{target|Target|token_id})}{\\&global ([figuredRange] [\\][\\]round(([\][\]round(((@(seltoken.left)-@(tartoken.left))**2 + (@(seltoken.top)-@(tartoken.top))**2)**0.5)\]\].value**2 + [\][\]@(seltoken.status.blue?all[0])-@(tartoken.status.blue?all[0])\]\].value**2)**0.5)\\]\\].value)} That could be further simplified by not requiring the first {&global} , and just using @{selected|token_id} in the place of every seltoken in the second {&global} structure, and using @{target|Target|token_id} in the place of every tartoken . But I find this version more readable. The end result of this is that you have defined the term figuredRange to be equal to the range between 2 tokens where you are using the blue markers for altitude. Now you could drop that term in another script's command line. For instance, if you wanted to write the distance between two tokens into bar1 for your selected token... setting bar1 to a value would typically look like this: !token-mod --set bar1|figuredRange So now we make two changes. We add the above syntax for defining figuredRange (so that it is defined in this message), and then, since that will introduce a targeting statement and we won't have a selected token for TokenMod to act upon, we'll add either the TokenMod --ids argument, or a SelectManager {&select} statement... either one referencing the id of the selected token. Here is what that line becomes using the TokenMod argument: !token-mod --set bar1|figuredRange --ids|seltoken {&global ([seltoken]@{selected|token_id})([tartoken]@{target|Target|token_id})}{\\&global ([figuredRange] [\\][\\]round(([\][\]round(((@(seltoken.left)-@(tartoken.left))**2 + (@(seltoken.top)-@(tartoken.top))**2)**0.5)\]\].value**2 + [\][\]@(seltoken.status.blue?all[0])-@(tartoken.status.blue?all[0])\]\].value**2)**0.5)\\]\\].value)} (If a player wants to run that command, TokenMod will need to be configured to have the players-can-ids option turned on.)