Understanding and using data types in Luau
- The player’s in-game money
- The spot the player is in during a race
- The number of criminals that they have arrested, or anything else
All of the mentioned examples are numbers. The in-game money can be 100, the race position can be 1, and the number of criminals arrested can be 3. In programming languages, we have numbers too. Numbers are our first data type.
Internal usage of the number data type
Sometimes, a difference between numbers and integers is made in the documentation. In Luau, integers are a part of the number data type. Internally, Luau changes between doubles, floats, and integers. If the documentation specifies an integer, you can expect the number to be stored as an integer internally. When a number is documented, it is internally stored as
long. Do not worry if this does not make sense. This knowledge is not required in Luau.
We can have more than just numbers. We can also have sentences. Examples of sentences can be the player’s username, a roleplay name, or a chat message. These sentences are called strings in programming. Strings are our second data type.
You might have heard of our third data type, a Boolean. A Boolean is
false. People often say programming is about ones and zeros, and true or false. There are no other possibilities for Booleans.
Creating a script
- First, create a new baseplate. Because the book assumes basic knowledge of Roblox and Roblox Studio, this is not explained.
- Once created, open Explorer. It should be visible by default. Search for something named ServerScriptService. You can see this in Figure 1.1.
- Right-click on ServerScriptService, select Insert Object, and add a new script. Make sure you did not accidentally make a
LocalScriptinstance. The difference is explained later in the book. Once added, the Explorer window should look like this:
Figure 1.1 – Your created script
- Double-click on the script you just created and you should see the following code in the script:
In Roblox, all scripts start when the game begins. We can start the game by pressing the Play button in Roblox Studio. Once pressed, you will see your character appear in a running game. The game still looks empty, as if nothing has happened. There are no scripts in a baseplate game by default, and the one we just added does not do much. However, it definitely does something. It just cannot be seen by a regular player. We have to open the Output frame to see this. To open the Output frame, click on the Output button under the View section, as shown here:
Figure 1.2 – Opening the Output frame
Instead of pressing the Play button, you can press the F5 key on your keyboard.
Once we open the Output frame, we see Hello world!. Looking back at the script we created, we see the Hello world! part. However, one part is missing in Output; this is the
print() part. That is because
print() is a function in Luau. Functions are explained later in this book. For now, remember that
print() prints the text that we passed to it in Output.
We should zoom in on the Hello world! part of the script. We previously learned that programming languages have sentences. They are called strings. “Hello world!” is a sentence; therefore, it is a string. We can see that this is a string because it is surrounded by quotation marks (
"). Roblox Studio also recognizes this as a string and gives it a particular color in your script.
Strings can be anything; go ahead, change the Hello world! part to something else, your name, for instance. Your script could look like this:
We now know what Hello world! means and what the
print() function does. Consider the
print() function as your trusted friend that will keep you informed on what your script is doing. This will help us to understand what is going on and come up with solutions for possible errors. In the following section, we will look at printing numbers.
There are more data types than just strings. You can print all of these data types. Let us start with numbers. Change your name to any number, for instance, the number eight. Your code might look like this:
If we run the game and open the Output frame, we can see that the number you chose was printed instead of your name. Did you notice how the number is the same color as the string in the Roblox Script Editor? As mentioned before, something that defines a string is quotation marks. The quotation marks are still there in the preceding code, but the correct number was printed. This is because the programming language still sees your number as a string. This is possible because numbers can be stored in strings too.
If we want to make sure our number is recognized as an actual number, we have to remove the quotation marks around the number. So, for example, your code could look like this now:
Notice how the color of the number changed in the Script Editor?
In this section, we learned how to print numbers and how to differentiate numbers from strings in our code. In the following section, we dive deeper into the unique things we can do with numbers, such as math operations.
If we run the code, we see the same line in Output. So, why bother making it a number instead of using strings? We previously mentioned that they are different data types. Different data types also serve different purposes. Numbers can do things that strings cannot do. Let us take a look at it from an easy perspective. In school, you used numbers during math. What did you use numbers for? Most likely to calculate things. You were adding, subtracting, dividing, multiplying, and whatnot. These are all things that you can do with numbers, whereas you probably had to write many sentences in English class. The chance is meager that you used multiplication on sentences.
Now that we have a number in our script, let us do some math. We start by adding the number three to the already present number eight. We do this by using the
+ operator. Try doing this for yourself. The script should look something like this:
print(8 + 3)
If we run the script, it should say
11 in Output. Congratulations, you have now made your first math operation in a programming language. However, we can do many more math operations. Try subtracting (
-), multiplication (
*), and dividing (
You can add multiple print statements below each other to create a larger script that performs multiple math operations at once.
Your code should look something along these lines:
print(8 + 3) print(8 - 3) print(8 * 3) print(8 / 3)
We have two more math operations that you can do on numbers: exponentiation (
^) and the modulus (
%). For exponentiation, you can do something like this:
print(8 ^ 3)
The result of this operation would be
512. What happens when using this operator is that the number before the caret (
^) gets taken. The number gets multiplied against itself as many times as stated behind the exponentiation operator. To make this easier, the operation
8 ^ 3 translates to
8 * 8 * 8. If we switched the numbers and made the operation
3 ^ 8, the operation would be translated to
3 * 3 * 3 * 3 * 3 * 3 * 3 * 3.
The last operator is the modulus. This operator is commonly forgotten, especially in Roblox programming. The modulus operator (
%) looks like a percentage; however, it is absolutely not a percentage. Do not let it fool you. The modulus operator takes the number behind the
% and multiplies itself as many times as it fits into the number before the operator. Once it reaches its limit, it subtracts its total multiplication from the first number and gives back the difference. This operator is not easy to understand.
To visualize it, we take the operation
8 % 3. The number three fits twice into the number eight, because three times two is six, and six is lower than eight. If we multiplied it once more, we would do it three times, resulting in nine. Nine does not fit in eight. Then, we subtract six from eight. What is left is two. The operation
8 % 3 would return two. This is probably the most confusing operator so far. It is confusing because it is never taught during math in school.
You can try to make a few operations in your script to test this operator yourself.
Combining math operations
print(8 + 3 * 2)
Notice how the result of this execution is 14? During math, you probably learned about the order of operations. The order of operation tells you in which order you have to execute each operation. In programming languages, we do the same. Luckily, it is the same order of execution taught in school. You probably heard of PEMDAS to help you remember this order. PEMDAS stands for Parentheses (
)), Exponents (
^), Multiplication (
*), Division (
/), Addition (
+), and Subtraction (
In the previous code example, the three times two is executed first. If we wish to execute
8 + 3 first, we can surround it with parentheses. Your code would look like this:
print((8 + 3) * 2)
The outcome of this math operation changed from 14 to 22. Do you see that there are two opening parentheses directly behind
We learned that we could do math operations with the number data type in the previous two sections. Previously, we learned about multiple data types. The following section explores the unique things that we can do with strings.
Now that we know how to use numbers, we can look at some of the cool things that you can do with strings. We cannot do math with strings, but we can combine them. When combining strings, we use an operator called concat, short for concatenate. This operator is two dots directly after each other (
..). Let us try to concatenate two strings in a
First, we need two strings. As shown in the following code snippet, this is done by enclosing the message with quotation marks (
"). Then, you can choose the sentence that you wish to insert into your string yourself. For this example, two strings that say “
Hello” and “
Laura” are combined:
print("Hello " .. "Laura ")
Hello Laura appears as one string in Output when you start your game. This operator is the only thing that you must use to concatenate two strings into one. Now, try to concatenate three strings into one by using what we just learned. As you might have guessed, it looks like this:
Now we know how to concatenate different strings into one. The following section teaches you about another unique thing with strings: escape characters.
If you want to display a string on the next line, we can add another print. Most of the time, this is not the ideal solution. There is a simple alternative for this. It is called a new line escape character. The name sounds more complicated than it is. This new line escape character looks like this:
\n. In the same script, suppose that we want to greet someone and tell them it is Monday on a new line. Your code should look something like this:
print("Hello Peter!\nToday is Monday! ")
If you run this script, Hello Peter! appears on the first line, and Today is Monday! appears on the second one.
Another practical escape character is for a horizontal tab. This escape character mimics the same thing that happens when you press the Tab button on your keyboard in your preferred text editor. This horizontal tab escape character looks like this:
\t. This escape character comes in handy when creating lists. For example, printing a shopping list can look something like this:
print("Shopping List:\n\t- Bread,\n\t- Butter,\n\t- Milk.")
Try to play around and create a few strings yourself. Practicing with strings is the best way to ensure you know how to use them.
We now know how to use the new line escape character and the horizontal tab escape character. Previously, we also learned how to concatenate two strings into one, and before that, we learned about the unique things that we can do with numbers. But what if we wanted to combine both data types into one
Casting data types
What if we tried to combine a string and a number in the same
print("4" .. 5)
For some reason, this statement prints
45 in Output. Behind the screen, the system sees a string trying to concatenate with a number. We know that strings can contain numbers. The system knows it too. So, Luau helps you out and turns the number
5 from your statement into a string that contains the number
5. Then, the two strings merge into one. As a result, we get an output of
Instead of letting the programming language figure out how to solve this issue, we can specify that we want to do it this way. We can use more functions besides the
print() function. One of them is
tostring(). This function turns any data given between the parentheses into a string:
print("4" .. tostring(5))
If we change the operator from a concatenation (
..) into an addition (
+), do we get an error?
print("4" + 5)
This code gives an error. This error occurs because you used an operator used for numbers on a string. But did we not use an operator used for strings on a number too? Yes, however, we know that strings can contain any character, including non-numbers. Therefore, Luau cannot change a string into a number unless we specifically tell it to do so.
We can tell Luau to change a string into a number using the
tonumber() function. For example, if we put the string that contains the number four into this function, our operation should work:
print(tonumber("4") + 5)
As expected, the result of this operation is
9 and not
45. However, what if we wanted to use the same string and number and get the result
45, while having both pieces of data as numbers and not strings? We can combine the
tostring() functions to achieve this:
print(tonumber("4" .. tostring(5)))
One disclaimer when using the
tonumber() function: this function does not always work. For example, if your string contains anything other than numbers, this function returns something called
nil. Nil means nothing. If you are not careful and your function returns
nil, and your script does not expect this, an error occurs. Try it for yourself:
print(tonumber("a5")) -- This will return nil. print(tonumber("a5") + 6) -- This will give an error.
Now we know how to cast strings into numbers and the other way around. We also learned how to combine numbers and strings in one statement. In the next section, we look at Booleans, our final data type.
Last but not least, we can also print Booleans. Printing Booleans is not very difficult on its own. However, there are some operations for Booleans as well. For now, let us start with printing
false. Your script should look something like this:
When printing Booleans, there are no quotation marks (
") required. The reason for this is because Booleans are not strings. Instead, they are a unique data type. In the next section, we look at logical operators.
Similar to the other data types, there are some operators that we can use to create operations with Booleans. These are the and (
and) and the or (
or) operators. There are no special characters for these operators; they are just text. However, these operators do have a particular name. They are called logical operators.
Let us start with the
and operator. To keep it simple, let us use a real-life example of asking your parents for permission to purchase a new game. The answers your parents give are Booleans, yes (
true) or no (
false). Because we are talking about the
and operator, you need both your parents to agree on purchasing a new video game.
print(true and true)
Roblox Studio might warn you when you enter this script because it already knows that the result is always
true. Therefore, the statement is redundant. However, to help you understand these operations, you can ignore the warning and execute the script.
Now, one of your parents says no. Make a script where one of the Booleans is
false, and execute it. Your script can look like this:
print(true and false) print(false and true)
As you might have guessed, when both your parents do not agree, and both Booleans are
false, the statement always returns
false. However, for the sake of understanding, you should try the script regardless. Your script can look something like this:
print(false and false)
and operator, Booleans also have the or (
or) operator. For the
or operator, we use a different example. Imagine you are selling something online. You only need one buyer that wants to pay the price you have set. In the best-case scenario, both customers are interested in purchasing your item. Your script looks something like this:
print(true or true)
The result of this is
true. The only problem is picking which person you sell your product to. This problem, however, is not something you have to solve through coding.
Now, only one person agrees. So, the code looks like this:
print(true or false) print(false or true)
Unlike with the
and operator, these both return
true. When selling an item, you do not need multiple sellers. One is enough to sell your item to. However, both would be
false when there are no sellers at all. The sale cannot go through. Your code looks like this:
print(false or false)
In this section, we learned all about data types. We learned about three different data types: numbers, strings, and Booleans. We learned how to print them to Output and about the special operations that we can do on them. We learned how to do math operations on numbers, how to combine strings, and how to use logical operators on Booleans. In the next section, we take these data types to the next level by using variables.
Introducing and using variables
Now that we know about the essentials of programming and data, we can start using this data to start doing things. In this section, we will learn about variables. We will learn what they are, what they are helpful for, how to update them, and how to improve the quality and readability of our code by using variables. Variables are all about temporarily storing your data somewhere. In Luau, the variables for all data types look the same.
- First, you define a variable by putting
localinto your script.
- Then, you put the name of your variable. The name of the variable can be anything. Try to make your variable names as logical as possible, as it helps when the size of your script starts to increase.
- Once your name is defined, you put an equal sign (
- Finally, you can specify the data that you wish to store in this variable. You can see an example of a variable structure in the following code:
local your_name_here = your data
You can consider variables as temporary boxes that store any data that you specify behind the equal sign (
=) under a specific name. Now, if we want to store a name, for instance,
Emma, in a variable, it looks like this:
local name = "Emma"
We learned that the quotation marks (
") around a sentence define a string. You can see this is the case for the preceding example, which means we just stored a string in a variable that is named
Lower and upper camel case
Variables can be named anything. However, it is custom to start your variable name with a lowercase letter. If your variable name consists of multiple words, the first letter of the first word is a lowercase character, and the first letter of each word after that should be a capital letter. There is no practical reason for this, and it is just for the readability of your code. Here are some examples of correct variable names:
local firstName = "Emma" local randomNumbers = 125 local isThePlayerAFK = false
This way of naming variables has a name. It is called lowerCamelCase. This method of naming variables is not unique to Roblox or Luau. Many tech companies around the world use it. It is a good habit to teach yourself to do this from the start.
Besides the lower camel case, another “camel case” is good to know. This other camel case is UpperCamelCase. The first character is capitalized with this naming method instead of using a lowercase character. You primarily use the upper camel case method when naming scripts.
Besides storing data, what can we do with it? Everything that you can do with the data you learned about. The only difference is that you can now use the variable’s name instead of direct data, as shown here:
local firstName = "Alexander" print(firstName)
Order of execution
Notice how we defined the variable before the print? The reason for this order is that the system reads the script line by line when the script gets executed. When it arrives at the line of the variable, it puts the variable into your computer’s memory. If it gets to the print first, it tries to find the
firstName variable in your memory. If the variable does not exist, it cannot be printed and gives an error. It is custom to put all of your variables at the top of the script to prevent this from happening.
The same output appears when you insert the string directly into the print function. However, when you have 10 different
Let us take a better example. We have a number that starts at zero. We updated it five times. Each time we update the number, the number gets printed. We only use one variable for the number that we have. Your code can look something like this:
The code you are about to see is imperfect, and we will improve it later. Methods for removing duplicate code are taught in Chapter 2, Writing Better Code.
local currentNumber = 0 print(currentNumber) currentNumber = currentNumber + 1 print(currentNumber) currentNumber = currentNumber + 1 print(currentNumber) currentNumber = currentNumber + 1 print(currentNumber) currentNumber = currentNumber + 1 print(currentNumber) currentNumber = currentNumber + 1 print(currentNumber)
Let us take a look at the preceding code. First, we see a
currentNumber variable that starts at
0. The first
print() puts the variable, with the value
0, in the Output frame. Then, it does something that we have not seen before. It takes the variable’s name, puts an equal sign (
=) behind it, states its name again, and does a math operation that adds one.
We start with what we know. We know how math operations work, and we know how variables work.
currentNumber + 1 is a math operation with a variable. We can assume that this works the same way as any other math operation. It takes a look at the variable’s value, which is
0 for our current scenario, and then adds
1 to it. The result of this math operation would be
1. What Luau does behind the screen is change the line that we are executing to this:
currentNumber = 1
Hopefully, the statement that we have right now looks a bit familiar. It is not an exact match. However, you might recognize it from how we create variables. The only thing missing from creating a variable and our current code is the
local part. We know that the
local part is used when creating a variable. What if the statement that we have right now updates an existing variable to a new value? It would make sense. Just translate our current statement to something you can say out loud: “Current Number Equals One.” The
currentNumber variable now has the value of one.
Hopefully, analyzing the code helps you realize what to do when you do not understand the code that you just read. First, try to look for the parts that you understand and figure out the rest from there.
Removing magic numbers
Now that we understand the script from the previous section, we know how to make variables and update them. But, as we said previously, the code is not ideal. Previously, we had an example where we incremented the number by
1. However, what if for our current example we do not want to increment a variable by
1 but by
2? We have to change our code in so many places. We could have prevented this by making a second variable that would determine the amount by which we would increment our variable. An improved version of the code would look something like this:
local currentNumber = 0 local incrementValue = 2 print(currentNumber) currentNumber = currentNumber + incrementValue print(currentNumber) currentNumber = currentNumber + incrementValue print(currentNumber) currentNumber = currentNumber + incrementValue print(currentNumber) currentNumber = currentNumber + incrementValue print(currentNumber) currentNumber = currentNumber + incrementValue print(currentNumber)
This code does what we initially wanted to do. Now, if we want to change our increment value from
3, there is only one spot we have to change it in. Using a variable makes it much easier to maintain for the future. Besides that, the code is a lot more readable as well. Before, there was just a number in your code; we had no idea what the purpose of this number was.
The number we just removed from our script has a name in programming. It is called a magic number. Magic numbers are pieces of data used multiple times in your script and do not explain what they do or what their purpose is, just like the example we just had. To prevent the usage of magic numbers, we can introduce a variable. Using magic numbers when programming is considered a code smell and should be avoided.
There is an even shorter way of writing this code. Notice how you were writing the current number variable multiple times per line? We do this because we have to define the variable that we are updating and also to get the current value of this variable. We can change the equals sign (
=) to an operator that assigns and adds (
+=) as follows:
local currentNumber = 0 local incrementValue = 2 print(currentNumber) currentNumber += incrementValue print(currentNumber) currentNumber += incrementValue print(currentNumber) currentNumber += incrementValue print(currentNumber) currentNumber += incrementValue print(currentNumber) currentNumber += incrementValue print(currentNumber)
Our code works the same, and the only difference is that we no longer have to write the variable’s name twice; we used it twice per line. Currently, we are using an operator that assigns and adds (
+=); however, there are other operators like this for different math operations. For example, we also have one for assigning and subtracting (
-=), assigning and multiplying (
*=), and assigning and dividing (
/=). Try using these new operators in a script similar to the one previously.
We just learned about a best practice to make our code more efficient while removing our magic number code smell. However, there is another best practice we can use to improve the readability of our code. The following section explains how to use constants in Luau.
So far, we have made an immaculate script. However, we can do one more thing to improve the readability of this script. Most programming languages have something called constants. Constants are a special type of variable. The value of these variables is set once and can never be changed while running the script.
Previously, we said that the final thing was to optimize the script’s readability. This is only for readability purposes because Luau does not have constants. However, constants have a unique method of naming. You learned to name variables by using the lower camel case method. For constants, you have to write the full name of the variable in capitals. When the name of your constant consists of multiple words, an underscore (
_) is added to separate the different words; this is something we can do in Luau. This way, other programmers know that this variable never changes, even though it is technically possible.
In the example we used, we can find a candidate for a constant. The
currentNumber variable gets constantly updated with a new value. This variable is not a candidate to become a constant. On the other hand, our other variable is an excellent candidate to become a constant. The variable only defines the amount that the
currentNumber variable is incremented by. If we turn this variable into a constant, our script looks like this:
local INCREMENT_VALUE = 2 local currentNumber = 0 print(currentNumber) currentNumber += INCREMENT_VALUE print(currentNumber) currentNumber += INCREMENT_VALUE print(currentNumber) currentNumber += INCREMENT_VALUE print(currentNumber) currentNumber += INCREMENT_VALUE print(currentNumber) currentNumber += INCREMENT_VALUE print(currentNumber)
If our script had been a bit different, our constant might have changed back to a standard variable. If, halfway through the script, we wished to change our increment value from two to three, it would have to be a variable again. As you can see, introducing a constant depends on what you wish to achieve with your script, and you have to look into the future as well. Do you wish to allow your script to be modified so this might be possible in the future? If so, it might be a good idea to keep it as a variable.
As you can see, when and when not to introduce a constant is a vague area. It is perfectly fine if you wish to never use constants in Luau. After all, Luau does not even have the implementation of a constant, and it is just about readability.
When in doubt about introducing a constant, do not do so. In Luau, it is better to keep a standard variable than to have an incorrectly implemented constant. This book, however, uses constants when required from now on.
Now that we know how to use variables and constants, we are ready to take our coding skills to an even higher level. The next section teaches us how to make our code perform different actions depending on our data.