Chapter 3 - Variables and Types
The very first thing that a programmer needs to know about programming is the concept of variables. If you've taken an algebra class in the past, the term may sound familiar, which is helpful as variables in algebra and variables in programming are similar.
Imagine that you needed to write a program that took some numbers and added them up. The first thing you would want to do is to tell the program what those numbers are. Say you told the program the numbers 3, 7, 2, 8, and 5. Well, the program is going to need a way to remember those numbers so that it can work with them later on.
This is where variables come in. A variable is a construct in a program that is designed to hold a value and store it under a label. For example, take a look at the following code.
int x = 5;
Let's break this down. The
int is telling the program what type a variable is, the
x tells the program that the variable's name is
x, and the the
= 5 tells the program what the variable's value is. In short, this line of code creates a new variable
x of type
int and gives it the value of
There are two things going on in this code. The first is that a variable is being declared, which means that the program is creating a new variable to remember. The second is that a variable is being initialized, which means a variable is being assigned a value for the first time.
Now that our variable has been created (declared), we can access it elsewhere in our program. If, say, we wanted to assign a different value to it, we could do the following:
int x = 5; x = 3;
Note that the
int is gone from the second line.
int is only required when declaring a variable for the first time. After that, the program knows what the type of
x is, so you don't need to keep telling it.
You can also use variables when assigning a value to other variables:
int x = 5; int y = x;
In this code, we create a variable
x and assign it a value of
5. Then we create another variable
y and assign it a value of
x. This means that we take whatever value is being stored in
x and copy it into
y. At the end of this code,
y will also be set to
int x; ... x = 5;
See how the first line doesn't assign a value to the variable
x? This is a declaration without an initialization. The value of a variable that has been declared but not initialized is the default value of the type assigned to the variable, which, in this case, is
0 due to the type being
The technical term for the name of a variable is an identifier. In general, you can name your variables whatever you want, but there are a number of rules and recommendations for how you do it.
First, the identifier must start with a letter in the alphabet (uppercase or lowercase) or an underscore character
_. Any identifier that starts with a number or other symbol will not be recognized and will cause an error in your script. After the start of the variable, you may use letters or numbers as well as an underscore character. You cannot use a space as part of a variable name.
// These are legal identifiers. int abcdef; int ABCDEF; int aBcDeF; int _abcdef; int abc123; // These are not legal identifiers. int 123456; int 123_456; int 123abc; int %$#^%^%; int abc def;
Second, the identifier cannot be one of a number of specific words. These words are called keywords, and they are reserved by AngelScript to mean various things. The full list of keywords are:
Following those two rules, you can otherwise name your variables whatever you like. However, a recommendation (a "soft-rule", if you will) is that you name your variables with an identifier that has to do with that variable's purpose. For example, if you have a variable that stores the water level in a pool, you might name it
WaterLevelInPool. While giving your variables ambiguous or nonsense names won't result in an error, it will result in your code being incredibly difficult to read and understand, even by you.
// Good variable names int WaterLevelInPool; int ExplosionCount; int NumberOfKills; int DistanceToLocation; // Bad variable names int a; int vakjnaldkjbv; int _________; int QQQQQQQ;
(While as a general rule it's a bad idea to give single letter names to variables, it is acceptable to do so in situations where the variable is used in a temporary setting.)
When we talk about a variable's type, we are referring to the kind of value or information that value stores. So far, whenever we've declared a variable, it's been with the type
int, which means that the variable stores a number of some description. There are quite a few different types to choose from, however, and which one you decide to go with depends on the role a particular variable will play and what kind of value it will store.
There are a number of types that are built-in with AngelScript. You can expect to find these types no matter which game you are programming for as long as you are using AngelScript.
Let's start with the integral types of AngelScript. These types are meant to hold numbers without decimal points.
|Type Name||Value Range||Default Value|
|int8||-128 to 127||0|
|int16||-32,768 to 32,767||0|
|int||-2,147,483,648 to 2,147,483,647||0|
|int64||-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807||0|
|uint8||0 to 255||0|
|uint16||0 to 65,535||0|
|uint||0 to 4,294,967,295||0|
|uint64||0 to 18,446,744,073,709,551,615||0|
These types are categorized based on two factors: size, and signedness.
- The size of a type is how much memory it takes up in the program. This size is generally measured in bits. An
int8, for example, uses 8 bits to store its value, whereas an
int64uses 64 bits. (The
uinttypes use 32 bits, but as 32 bit the most frequently used size, the
32part of the names have been chopped off for the sake of convenience.)
- The signedness of a type is whether or not the values in the type can have a sign, or, in other words, whether or not the type supports negative numbers. If you compare
uint8, you'll see that the range of
127, whereas the range of
255. The number of possible values in both cases is still the same (256 possible values), but the "signed" type has been shifted over so that 0 is in the middle of the range instead of the beginning.
Next, we have what are known as the floating-point types. These types are for representing numbers with decimal points.
|Type Name||Value Range||Smallest Positive Value||Maximum Number of Digits||Default Value|
You can see from the table that the floating-point types aren't quite as straight-forward as the integral types. Instead of a nice clean minimum and maximum value, we have a bunch of decimal numbers in scientific notation. This has to do with how floating-point types are stored in memory. That topic is fairly advanced, so I won't go over it here, but if you're curious, the process is described here.
The size of a
float is 32 bits, whereas the size of a
double is 64 bits. Size is a factor in floating-point types as well, but instead of being for the range of the value (although that is affected too), the size of a floating-point type has to do with its level of precision. As you can see in the table, the maximum number of digits you can use is 15 digits for a
double, but only 6 digits for a
float. These aren't hard limitations, however, but merely guarantees of accuracy. If you were to use a
float value with more than 6 digits, say,
1234.5678, the program cannot guarantee the precision of that number. If you were to check that number while the program was running, it might have an actual value of the number might actually be something like
1234.562. This is because of rounding errors. The reason for it, again, has to do with how floating-point numbers are stored in memory, but you don't need to worry about the details too much. As long as you stay within the recommended number of digits, it should never be a problem.
There is one more built-in type for AngelScript, and it has nothing to do with numbers:
|Type Name||Possible Values||Default Value|
bool type name is short for boolean. Boolean values are restricted to one of two values: true or false. Booleans have to do with whether something is or is not. For example, some boolean variables you might store could be:
bool IsLightOn = true; bool HasPlayerEnteredArea = false; bool DidILeaveTheOvenOn = true;
Beyond the built-in types of AngelScript, there are a number of other types that are specific to HPL3. If you were to go to another game that uses AngelScript (such as Wolfire's Overgrowth), chances are that that game's modding system won't have these types available (though it's possible they will have equivalents).
|Type Name||Possible Values||Default Value|
In HPL3's AngelScript, a
tString is a specific flavor of a string, which is a sequence of characters, letters, and numbers. It doesn't have a fixed length, so it can be anything from
"Greetings, sirs, my what a lovely fine evening we have here. Might you fancy a cup of tea?".
The most common way to use a
tString is to store some kind of word or label, such as when you want to display a message on the screen that the player will read. There are some handy functions that you can use with a
|length||Gets the number of characters represented by the string.|
|resize||Resizes the string to be the specified length. (Removes characters or adds "null" characters as necessary.)|
In addition to variables that store a single value, there is also a type of variable that holds many values. These variables are called arrays.
Some languages allow you to create arrays that can store anything, but in AngelScript, arrays can only hold a single type. This type is chosen when the array is first declared:
array<int> intArray; array<bool> boolArray; array<tString> stringArray;
In the above example, the type name inside the angled brackets is the type of value that array can store. For example, the
intArray can only store integers, and the
stringArray can only hold string values.
That's all well and good, but how do you get at the values in the array? That is done using something called indexer notation. Let me show you how it works:
lightLevels = 5.0; float lightLevel = lightLevels;
The square brackets (along with the number inside them) make up the indexer notation. On the first line, we are taking the value
5.0 and storing it in the array at an index (in this case, index 0). The second line we are taking the value in the array at index 0 and assigning it to the variable
You don't have to just use index 0 either. You can use any index you want. A good rule of thumb, however, is to keep your values sequential, which means that if you have 10 values to store, store them in the array at indices 0 through 9.
In addition to adding a value at a specific index, there are also different ways you can more dynamically access an array. These ways use the array's functions, which we will get into in Appendix 2. For now, these are the more useful functions of an array and how they are used:
|length||Gets the number of values stored in the array.|
|push_back||Adds a value to the end of the array. (If indices 0-4 contain values, the new value is stored at index 5.)|
|resize||Resizes the array to t|