Using Token Bar fields to hold multiple variables I have some new roll20 players and GMs in my area, and some aren't too keen on learning to write macros or use roll20 sheet templates to get all their PC and opponent actions loaded for quick use in-game. Without some prior experience, they find the task daunting, especially if the pre-work time exceeds the time they'll need to muddle through keyboard or advanced die roller entry for the rolls they'll actually need in-game. But for the game to proceed in a timely fashion, I wanted everyone to have a few basic token actions they could use with any token (PC or opponent). So I turned to the token bar fields - maybe we could put some key stats in there? Sadly, there were only 3 such fields, or 6 if you count the bar max fields - not enough to hold even a basic set of stats if you want to automate a high percentage of rolls. But then I thought, I can do math , and why not make a few of these fields hold multiple parameters, in a string of numbers I could parse according to a standard format? So I did. Note that I am a free subscriber, so I don't have access to IF statements, but I found another way: Devise a standard format for the digits each bar field should hold, and write a macro to test the setup Make use of the floor() function and modulo operator ( % ) to select specific portions of the numeric field for token action macros Use " 0+ " in macros as a crude error handler for null values (forced data type conversion to numeric) Put roll queries in your macros for anything that won't be numeric (I did this for damage rolls; "2d6+9" is not a number until you roll it) Season to taste Here is a setup check macro for a setup that uses some 6-digit token bar entries, and cuts them up into three 2-digit fields: **Setup2 Check**
Bar 1 (Melee/Ranged/CM): [[floor(0+@{selected|bar1}/10000)%100]] [[floor(0+@{selected|bar1}/100)%100]] [[floor(0+@{selected|bar1}/1)%100]]
! Digits 1-2 Melee Attack Bonus (0-99), digits 3-4 Ranged Attack Bonus (0-99), digits 5-6 Combat Maneuver Bonus (0-99)
Max 1 (Stealth/Perc./Init.) [[floor(0+@{selected|bar1|max}/10000)%100]] [[floor(0+@{selected|bar1|max}/100)%100]] [[floor(0+@{selected|bar1|max}/1)%100]]
! Digits 1-2 Stealth mod (0-99), digits 3-4 Perception mod (0-99), digits 5-6 Initiative mod (0-99)
Bar 2 (AC/Touch/CMD) [[floor(0+@{selected|bar2}/10000)%100]] [[floor(0+@{selected|bar2}/100)%100]] [[floor(0+@{selected|bar2}/1)%100]]
! Digits 1-2 AC (0-99), digits 3-4 Touch AC (0-99), digits 5-6 CMD (0-99)
Max 2 (Save Mods F/R/W) [[floor(0+@{selected|bar2|max}/10000)%100]] [[floor(0+@{selected|bar2|max}/100)%100]] [[floor(0+@{selected|bar2|max}/1)%100]]
! Digits 1-2 Fort save mod (0-99), digits 3-4 Reflex save mod (0-99), digits 5-6 Will save mod (0-99)
Bar 3 (HP) [[@{selected|bar3}]] Max 3 (HP max) [[@{selected|bar3|max}]]
! Any integer value is allowed for either field, although HP should never exceed HP max The floor(x/10000) , floor(x/100) and floor(x/1) statements remove digits from the right of the string (the last 4, 2, and 0 digits respectively). %100 removes digits from the left of the string (anything beyond the rightmost 2 characters). Voila! Right and/or left trimmed returning 2 digits. Here's an example of a token action macro to roll all 3 saving throws using the numeric string defined for saving throw modifiers: ! Requires Setup2
@{selected|token_name} Saves
Fort [[1d20 +[[floor(0+@{selected|bar2|max}/10000)%100]] ]] Ref [[1d20 +[[floor(0+@{selected|bar2|max}/100)%100]] ]] Will [[1d20 +[[floor(0+@{selected|bar2|max}/1)%100]] ]] A more complicated version reads multiple tokens for attack and defense values when making a full attack: ! Requires Setup2 for both attacker and defender
**@{selected|token_name} attacks @{target|Defender|token_name}**
?{Attack Type|Melee, [[1d20 + [[floor(0+@{selected|bar1}/10000)%100]] ]] vs AC [[floor(0+@{selected|bar2}/10000)%100]] |Melee Touch, [[1d20 + [[floor(0+@{selected|bar1}/10000)%100]] ]] vs AC [[floor(0+@{selected|bar2}/100)%100]] |Ranged, [[1d20 + [[floor(0+@{selected|bar1}/100)%100]] ]] vs AC [[floor(0+@{selected|bar2}/10000)%100]] |Ranged Touch, [[1d20 + [[floor(0+@{selected|bar1}/100)%100]] ]] vs AC [[floor(0+@{selected|bar2}/100)%100]] |Maneuver, [[1d20 + [[floor(0+@{selected|bar1}/1)%100]] ]] vs CMD [[floor(0+@{selected|bar2}/1)%100]] } #_Damage
?{2nd Attack Type|Melee, [[1d20 + [[floor(0+@{selected|bar1}/10000)%100]] - 5 ]] vs AC [[floor(0+@{selected|bar2}/10000)%100]] |Melee Touch, [[1d20 + [[floor(0+@{selected|bar1}/10000)%100]] - 5 ]] vs AC [[floor(0+@{selected|bar2}/100)%100]] |Ranged, [[1d20 + [[floor(0+@{selected|bar1}/100)%100]] - 5 ]] vs AC [[floor(0+@{selected|bar2}/10000)%100]] |Ranged Touch, [[1d20 + [[floor(0+@{selected|bar1}/100)%100]] - 5 ]] vs AC [[floor(0+@{selected|bar2}/100)%100]] |Maneuver, [[1d20 + [[floor(0+@{selected|bar1}/1)%100]] - 5 ]] vs CMD [[floor(0+@{selected|bar2}/1)%100]] } #_Damage
! _Damage macro call will not ask for dice and modifiers a second time if attack types differ (e.g. trip + stab) This works with a separate roll query for damage (roll single attack macro if threats are indicated; roll more damage directly if x3 or x4 crit confirmed): Damage [[ ?{Damage Dice|1}d?{Die Type, d|6} + ?{Modifier|0} ]] I have another version for low level play, where saving throw, attack, skill check and initiative modifiers will not exceed +9. The advantage here is that it is a lot easier to read 3 digits in a token bar bubble versus 6 digits. You could potentially mix and match and have different field lengths in the same numeric string, but the method requires the length to be consistent for all tokens in the game. If you use a 2-digit field and the token's value is 9 or less, a zero must be entered for the first digit in the field. **Setup1 Check**
Bar 1 (Attack Mod) [[@{selected|bar1}]]
! Any integer value is allowed
Max 1 (Perception/Init. Mods) [[floor(0+@{selected|bar1|max}/10)%10]] [[floor(0+@{selected|bar1|max}/1)%10]]
! 1st digit perception mod (0-9) and 2nd digit initiative mod (0-9)
Bar 2 (AC): [[@{selected|bar2}]]
! Any integer value is allowed
Max 2 (Save Mods F/R/W) [[floor(0+@{selected|bar2|max}/100)%10]] [[floor(0+@{selected|bar2|max}/10)%10]] [[floor(0+@{selected|bar2|max}/1)%10]]
! 1st digit Fort save mod (0-9), 2nd digit Reflex save mod (0-9), 3rd digit Will save mod (0-9)
Bar 3 (HP) [[@{selected|bar3}]] Max 3 (HP max) [[@{selected|bar3|max}]]
! Any integer value is allowed for either field, although HP should never exceed HP max At this point, floor() and modulo ( % ) presume base 10 operands. To shorten the number of characters, I considered whether hexadecimal or other systems might be used for single-character representation of modifiers. There might be a way to incorporate something with ASCII conversion to turn character strings into numeric strings prior to mathematical parsing, but the HTML for that is beyond my ken at the moment. Perhaps someone else can create a little macro for that that reads a string of characters and converts it into a string of 2-digit decimal numbers per this table: <a href="http://www.asciitable.com/" rel="nofollow">http://www.asciitable.com/</a>