- Anatomy of a Sheet Worker
- Events, and watching Attributes
- Variables – How to Name Things
- Arithmetic in Sheet Workers
- What If? in Sheet Workers
- Logging in the Browser Console
- Strings, Arrays, and Loops
- Asynchronicity and Things to Avoid With Loops
- Changes and the eventInfo Object
- Action Buttons
- setAttrs and Saving Attributes
- A Sheet Worker Reprise
- Castle Falkenstein Design – Sheet Workers
- The Perils of Sheet Worker Functions
- The Script Block and Identifying Characters
- Arrays and Dropdowns
- Undefined and Other Error Values
- The Ternary Operator – The One-Line If
- Template Literals
- Functions and the Fat Arrow
- Strings in Sheet Workers
In Anatomy of a Sheet Worker, we learned how to collect attributes, and we learned a bit more about how to Create Variables, and the difference between Numbers and Strings. Now we can do some stuff.
The simplest thing is to perform arithmetic of various sorts. Here are some different calculations:
You can add (+), subtract (-), multiply (*), divide (/), and more. But addition and division are usually all you need. But you also can do this:
dex += 5; agl -= dex;Code language: Markdown (markdown)
The +-, -=, *=, and /= syntaxes are shorthand. Instead of typing this:
dex = dex +5;Code language: Markdown (markdown)
you can simply type:
dex += 5;Code language: Markdown (markdown)
There is a difference between += and =+, but it’s very subtle and pretty much always irrelevant in sheet workers, so you can ignore it and use either order.
You often round an attribute (to the nearest, rounding down, or rounding up). This is where the math object comes in. You can use Math.round (round to nearest), Math.floor (round down), or Math.ceil (round up):
The Math object has a bunch of functions attached to it, and they operate on anything in the brackets.
The middle example calculates a stat bonus appropriate for games like D&D (stats of 10-10 have 0.)
The last example rounds to hundredths. So you might want to know (say) dollars, and with cents as decimals. So if you start with something like 17.2465, it will be rounded to 17.25. You never have more than 2 digits after the decimal point.
Calculations can often lead to the same result in different ways.
Again they are two different ways of calculating the same result. Just do what feels right to you.
The Max and Min functions are very useful, and I use them maybe more often than I use the rounding functions. Each works the same way – supply a group of numbers separated by commas and it’ll tell you the largest or smallest.
They are great for limiting values. Say you want to add dex and agl, but the minimum score must be 0:
Each value to evaluate must be separated by a comma, but you can include calculations in each ‘value’.
You can also nest max and min (and any other function). Say the sum must be at least 0, but no higher than 30, you could do:
Here Math.max has been nested inside Math.min. When doing this kind of thing, make sure you keep the number of brackets right, and remember to use min and max correctly. Min gives you the smallest number of the set, and max gives you the largest number. I frequently do these the wrong way around, and have to correct myself!
When you want to create a random number, you have a special ability on roll20 – you can use the dice function. But that’s a bit complex (and will be covered later, under Custom Roll Parsing). In the meantime, if you want to create a random number, you can use the Math.random() function.
This function generates a number between 0 and 0.999999999 (recurring), so you need to multiply by a value to get a dice value, then add 1 otherwise it’ll start at 0. For example, a d6 would be
You need to round off because it generates numbers like 0.453267, and you need to round down, and then add 1.
You can use this to create a dice roll function, and we’ll come back to that in the post on loops.
Math.sign gives you the sign (whether a number is positive or negative). This is handy when constructing strings. By default a number will be shown like 17 if positive, and -17 if negative. But you might want positive numbers to be shown like +17.
To understand this needs if statements, and ternary operators, which are covered later, so this is shown as an example without much explanation for now.
This is easily done with Math.sign. Math.sign gives a value of -1 for negative values, 1 for positive values, and 0 for 0 or -0. So think about what you want to happen, and construct an if statement that works for that:
This example uses let in place of const because the value of the variable might change.
It also uses + to add two elements in a string, so if the score has a value of 17, it will be shown as +17.
And that is of course wrapped in an if statement. You’ll learn more about those in the next post.
The Math object has a lot of useful functions buried in it (and some that are useless for character sheets). Here’s a list of Math functions I have found useful, most of which have already been mentioned:
- Math.round: Round to nearest whole value.
- Math.ceil: Round up.
- Math.floor: round down.
- Math.max: pick the largest number out of a group.
- Math.min: pick the smallest number.
- Math.random: Generate a random number. handy for creating your own dice functions.
- Math.sign: report the sign of a number. positive = 1, negative = -1, 0 = 0.
- Math.abs: Convert a number to its absolute value, removing its sign.
- Math.pow: calculate the power of a number. Math.pow(number, 2) gives the square of a number, and Math.pow(number, 0.5) gives the square root.
In this post, we described how to perform simple arithmetic. In the next post, we’ll cover conditional calculations – using if statements. You’ll find these very, very useful.