- Anatomy of a Sheet Worker
- Events, and watching Attributes
- Variables – How to Name Things
- Arithmetic in Sheet Workers
- What If? in Sheet Workers
- JavaScript Objects
- Getting Loopy With JavaScript
- 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
- 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
- A Sheet Worker Reprise
This series will guide you in how to write better Sheet Workers. You don’t need everything in this series – you can just refer back to the previous post for all the basics. But if you want to write better sheet workers, you’ll need to understand variables.
This is one of the must fundamental aspects of Javascript (the language used to create Sheet Workers). You can write SWs without variables, and you’ll see a lot of sheet workers written by better coders that omit them. In my opinion, this is a mistake. Attitudes to variables are often as follows:
- Beginning coders use variables because they don’t know what they are doing, and are following guides like this one which show how to use them.
- Intermediate coders who have enough knowledge to be dangerous. They often omit variables where they can because they think it makes their code better.
- More advanced coders use variables because they realise it makes their code easier to debug, and it makes their code easier to understand for those of all skill levels that follow them.
You might detect a small bias here. But even if you don’t use variables, you need to understand how Roll20 and JavaScript store and use data.
What is a Variable?
A variable is a placeholder. You use them already, and all the time. When you remember that a banana is $10, and realise you can get 5 of them with $50, you have used a variable and also performed some algebra.
let banana_cost = 10;
let money = 50;
let my_bananas = money / banana_cost;
let money_left = money - (my_bananas * banana_cost);
Code language: Markdown (markdown)
So basically you create a variable for everything you want to use in your code.
Before we continue, it’s handy to know you can create comments in your code. Comments are parts of a code that Roll20 and JavaScript ignore. You can put anything in a comment, and it is invisible to your code. You’d put any needed explanation inside comments.
// a single line comment starts with two slashes
// these comments can start anywhere but end at the first line break
let banana = 10; // so you can put a comment here
/* if you want more control of comment, start it with /*.
that comment will continue until you manually end it with */
let money /* these comments can be placed anywhere */ = 50;
Code language: JavaScript (javascript)
There’ll be more about comments in the post on Logging and Errors.
Creating – or Defining – a variable is done in a specific way, using keywords of let, const, or var.If you aren’t sure which to use always use let. The code in the first tab could have been written this way:
const banana_cost = 10;
let money = 50;
let my_bananas = money / banana_cost;
money = money - (my_bananas * banana_cost);
Code language: JavaScript (javascript)
- let: use this when you are creating a variable that can change.
- const: use this when creating a variable which cannot change.
- var: this is a now-obsolete way of creating variables. You will see older sheet workers using it, but for good practice, you should replace any vars with lets.
You can create empty variables, but javascript will try to guess its data type (see below):
let money; // no value is declared, so this could be any type of data.
Code language: JavaScript (javascript)
This can easily trip you up. There are things you must do, and things you should do.
- Variable names cannot begin with a number
- Variable names can contain only letters and numbers- no spaces or special characters
Here are some rules to follow that you can break, but following them will make your life easier:
- Use all-lower-case for variable names.
- Use snake case (snake_case) for variable names. Avoid other naming conventions (camelCase, PascalCase, or kebab-case).
- Use these same rules in html and in sheet workers because you can sometimes use html names in sheet workers.
The idea is to always divide multiple words with _ (underscores) rather than spaces, and always use lower-case. There are some situations in Roll20 where this can cause problems (repeating section and action button names should have exactly one underscore) and in these cases it’s better to just use one single word (or kebab-case if you must have multiple words), but those are infrequent and you don’t need to worry about them yet.
The Most Common Types of Variable and Data
Each item or variable has its own data type. JavaScript is what’s called a weakly typed language – it is not as strict as some programming languages when it comes to handling data, and tries to switch between one data type and another on demand.
This can be convenient, but it can also be frustrating, especially when you need a variable to be of one type of data (which does happen). I’ll explain how to coerce variables into one type or another later, but for now here are the main types of variable you will encounter.
A string is basically any single value that isn’t a number, typically words and sentences. Strings are enclosed in quotes, like “Harry”, “This is a string”, and “3”. Notice that last one looks like a number, but because it is in quotes it is a string. You’ll find what difference that makes soon.
By default, Roll20 stores all data as Strings, so if you want to perform arithmetic (and usually you do), you need to convert that data to a number. I’ll describe how to do that in the next few tabs.
The main thing you do with strings is concatenation – which is the technical way of saying “combining together”. This confusingly uses +, so it looks just like arithmetic.
let word = "banana";
let sentence = "a bunch of";
let final_sentence = sentence + " " + word;
// this produces "a bunch of bananas"; not the insertion of a space.
Code language: JavaScript (javascript)
When you try to concatenate two variables (say “2” and “3”) and end up with them concatenated (“23”), you can tell JavaScript is treating them as strings. You’ll fix this by forcing those first values to be treated as numbers.
Integers are “whole numbers” like 0, 1, 2, 3000, -5, and so on. Outside of things like encumbrance, this is probably most of what you want to use in your sheet workers.
let first_integer = 5;
let new_value = (5 * 3) + 2
let third_integer = first_integer + new_value;
Code language: JavaScript (javascript)
When creating a new integer, you can calculate its value in any way available to JavaScript, and that includes using other variables.
Integers can be positive or negative but do have a maximum value, a ridiculously large number: 9,007,199,254,740,991. If you somehow exceed that, you’ll get an error (an undefined value) – you’ll learn more about those in the post on Logging and Errors.
Numbers, more properly called floating point numbers, are any numbers with a decimal or fractional value, like 3.3, 7.62, 0.001, -937567.01, and so on. In many programming languages, the difference between integers and floating point numbers is very important, but JavaScript generally doesn’t care. You can use them interchangeably.
This does mean if you specifically want an integer, you might have to create one. You can use the parseInt() function to do this (and parseFloat() to make sure you have a floating point number).
let a_number = 10.57;
let an_integer = parseInt(a_number); // this will give the number 10.
Code language: JavaScript (javascript)
There are other ways to do this – we’ll get more into that in the post about arithmetic.
Booleans are special variables that can only have two values, true and false.
This is a good time to talk about truthy and falsy values. These will be very important in the post on if statements. In Javascript, everything is truthy (like true) or falsy (like false). If a value is of the following values it is falsy:
- 0 (the number zero)
- “” (an empty string)
- false (the boolean value)
- NaN (Not A Number, a special value we’ll explore later)
- null (another special constant)
- undefined (another special property you’ll see a lot more of later).
If the value is not one of those 6 values, it is truthy (which is like true, and you can treat as if they were true for logical tests).
You’ll learn about logical tests later, and boolean values and truthy/falsy values will be very important.
An array is not strictly speaking a data type itself. It is a collection of things, which can themselves be of any data type including other arrays!
let empty_array = [];
let filled_array = ['a string', 50, ['another array','with 2 items'] ];
Code language: JavaScript (javascript)
You’ll learn more about arrays later, but the main thing you need to know is you can grab individual items by their index, and the index starts at 0. This index is more properly called a key.
let filled_array = ['a string', 50, ['another array','with 2 items'] ];
let first_index = filled_array[0];
let second_index = filled_array[1];
Code language: JavaScript (javascript)
first_index grabs filled_array’s first item, so has a value of ‘a string’. second_index has a value of 50.
Arrays are very versatile and will be covered in more detail when Getting Loopy in JavaScript.
Objects, or Javascript Objects, are both a data type and a collection, like arrays. You’ll se a lot more about these on the posts covering getAttrs and setAttrs, but they also are very useful in themselves. For now, I’ll just describe how to create them and a common way to extract data from them.
let empty_object = {};
let full_object = {
str: 15,
"a variable": "here's the value"
}
Code language: JavaScript (javascript)
You can extract data from an object with two syntaxes:
let dot_syntax = full_object.str;
let bracket_syntax = full_object["a variable"];
Code language: JavaScript (javascript)
You’ll learn more about these later. But basically, use the dot syntax when you know the item’s name and it is a valid variable name. Otherwise, use the bracket syntax.