Scripting is the act of utilizing preexisting elements (provided by a game engine) in efforts to control/create new aspects of the game. TorqueScript is the scripting language of the Torque Game Engine, of which Blockland was made. This article will provide insight on how to write TorqueScript in order to make Add-Ons for Blockland.
Getting Started
Console
The console is a very powerful tool in Blockland. It allows us to execute TorqueScript in real-time while viewing outputted messages or data from our code. To open the console in-game, press the tilde [ ` ] button for most computers if not the one half [ ½ ] or section sign [ § ] button for others.
Editor
Aside from the console, a text editor is one of the most important parts of scripting. Obviously, you need to have one in order to edit your code saved in files with the extension of ".cs". Although, any text file containing valid TorqueScript may be executed by Blockland. The following are examples of editors commonly used with writing TorqueScript:
▪ Notepad is the standard text editor for every Windows system. But if you are going to read long texts, it will be hard.
▪ Notepad++ is an integrated development environment (IDE) with a wide usage in many programming languages. It does not support TorqueScript, but due that the extension ".cs" represents a C# formatted file, it is recognized as C#.
▪ Torsion is an IDE created for TorqueScript by Sickhead Games. It color-codes everything in TorqueScript, which helps with managing and debugging. Sadly, costs $39.95 for individual use.
▪ Wordpad can be used as a replacement for Notepad. Reading long files in Wordpad is easier.
Hello World
Commonly, the very introduction to a programing language is the "Hello World" statement. It provides a basis on how program execution handles in the language. For TorqueScript, you would start by typing the following into the input bar of the console.
echo("Hello World");
This would output the message "Hello World" in the console output window.
See call for a better explanation.
State.ments
Statements are the basic foundation of scripting. Practically everything included in your script is a statement. Three main statement types associated with TorqueScript are assignment, call, and return. They are ended by semicolons [ ; ] allowing you to include multiple statements on the same line, like so:
echo("Hello World"); %variable = 123;
Assignment
Assignment statements are use to define variables. They work by stating the variable to be assigned, an equal sign [ = ], and the value, like so:
%variable = 123;
Variables can also be assigned the value of other variables, like so:
%otherVariable = %variable;
Call
echo("Hello World");
This is a call statement that executes the function echo with the string argument "Hello World". Call statements are used by stating the function to be used and stating the arguments inside parenthesis [ ( ) ] that are separated by a comma [ , ], like so:
echo("Hello World","Taco");
Return
Return statements are used to send feedback from a function. To retrieve the feedback from a function, a call statement of the function is used. It would be implemented by stating return and the value, like so:
function testFunction()
{
return "Hello World";
}
echo(testFunction());
This echos the returned value of testFunction, which is "Hello World". Return can also be used to define variables with the assignment statement, like so:
%variable = testFunction();
Mathematics
Expressions
Expressions can be exercised anywhere in TorqueScript, formatted like so:
1 + 2
This would evaluate to 3, as simple math puts it. Expressions can be used like functions to be manipulated as variables and values. The following is an example of how expressions can be used for arguments:
echo(1 + 2);
This would display 3 in the console. They can also include variables in the expression, like so:
%variable = 2;
echo(1 + %variable);
This would still display 3 in the console.
Expressions in TorqueScript still follow the standard order of operations.
Arithmetic Operators
Operator
Description
+
Addition
-
Subtraction
*
Multiplication
/
Division
%
Modulus
These arithmetic operators would work very much like you would imagine them to. Although, it is very likely that you may have never heard of modulus.
Modulus and more complex mathematic functions are explained in Mathematics - Advanced.
Functions
Functions are grouped sections of script that execute when called. The main purpose of their existence is to allow the ability to use code multiple times without having to write the same block of code every use. They can be defined with the word function, the name of the function, the arguments included in parenthesis [ ( ) ], and the code within curly brackets [ { } ], like so:
function test(%arg1)
{
%arg1++;
}
echo(test(1));
This would return 1 more than %arg1 (2 in this case) since TorqueScript automatically returns the value of the last statement.
Return can also be used elsewhere within the function using a return statement, like so:
function test(%arg1)
{
if(%arg1)
return %arg1;
else
return -1;
}
echo(test(1));
Variables
A variable is a value that can change according to the input of the program. In TorqueScript, they are in this format
%variable
with a percent sign and then the variable name.
Thanks to TorqueScript, we do not have to tell the game that we are going to use a variable, or what type it is.
Numerical
As you can probably guess, any variable with a number value.
You most commonly use arithmetic operators on these, used to store things like your health, BL_ID, velocity, and other values.
Strings
Strings are lines of characters, used in keyboard input and how the program figures out what to do with a function based on text.
echo(4+4);
Earlier, we mentioned this function.
When you input 4+4 or 8 into the echo function, it displays the value 8 to the console. (We will talk more about how this works in functions) Well, if we do this
echo("Hello world!");
it displays the value (as a string) "Hello world!" to the console.
Variables are placeholders for changing values, so if we used a string variable that was inputted by the user, it would display that.
echo(%string);
(Example of how you could display a string variable.)
Arrays
One element that the Torque Game Engine lacks in is arrays. That is to say, there are no arrays in TGE. There is a system that currently resembles arrays, but unlike in other systems these "arrays" cannot be passed as the product of a function. In fact, arrays are nothing more than a bunch of variables. Lets give some examples.
%var[0] = 0;
%var[1] = 1;
%var["dog"] = "bark";
%var["cat"] = "meow";
Those are TGE's arrays. Be aware that %var is a completely different variable and returning %var will not return any sort of array.
The brackets are very fancy, but after entering in the above code, doing the following...
echo(%var0);
echo(%var1);
echo(%vardog);
echo(%varcat)
returns...
01barkmeow
This is because arrays in TGE are nothing more than average, run-of-the-mill variables.
The one advantage to using "arrays" is dynamic variable names. Lets look at the following snippet of code:
for(%a = 0; %a < 5; %a++)
{
%var[%a] = %a + 1;
}
for(%b = 0; %var[%b] !$= ""; %b++)
{
echo("%var[" @ %b @ "] = " @ %var[%b] @ ";\n");
}
echo(%var3);
This return the following.
%var[0] = 1;
%var[1] = 2;
%var[2] = 3;
%var[3] = 4;
%var[4] = 5;
4
As you can see, using variables has some use. Just remember that, unlike in most languages, arrays aren't actually one thing that can be passed around.
Global Arrays
Global arrays have a lot more functionality to their local variants. This is because the arrays exist outside of a single function, meaning its accessible everywhere. This is a syntax for a Global Array.
$Global::Variable::Node[0]
Note that the following is a syntax error. Global Arrays can only have arrays on the final segment.
$Global::Variable[5]::Node[0]
Global Variables are very handy in storing hash tables of client data. You can do this by tagging the client's BL_ID to the end of the array. This is a good example of loading, and saving a client's data.
exec("config/server/myModData.cs"); // Executes the config file, loading the global variables.
$MyMod::Money[%client.bl_id] = 9001; // Sets the client's money.
export("$MyMod::*", "config/server/myModData.cs"); // Exports the $MyMod:: Global to the specified file.
Program Flow
Program flow is directing the flow that the program executes statements. If you imaging that the computer is reading through your script, like you read instructions for assembling your new chair, the computer reads from top to bottom (like we do). Say in your instructions for that chair, they tell you to go to page 5 if you have purchased their rocking chair, and to go to page 10 if not. (Some companies are lazy and write one instruction booklet for both products.)
Without program flow, all computers would just be like a movie, they would just do things without being controlled from start, to finish. This would be very boring, and would eliminate the purpose of a video game.
If - Else
The If statement works exactly how it sounds.
if(%var == 5)
{
echo(%var);
}
Program flow statements usually use brackets just like the functions do. We use ==, if(%var = 5) would assign 5 to %var, == checks to see if they're equal. %var == 5 would return a value of 1 if they were equal, and 0 if not. In an if statement, the block of code is executed if whatever is in the parenthesis is true or not 0. This makes sense because if %var was 6, %var == 5 would return a 0, and the if block would not execute.
You could do something like this:
if(1)
{
echo("Hello World");
{
Although it would be pointless because the if would execute no matter what.
The else statement is another block of code that is executed if the if is not true.
Like this:
if(%var == 5)
{
echo("Var is equal to 5");
}
else
{
echo("Var is not equal to 5");
}
Objects
Objects is like a box. You can put different kinds of things in it. Variables, functions and other objects. These is really good to be used to collect specific codes and algorithms into the box making it easier, and more secure, to use them. You do not even have to use global variables. An object can be used like a normal variable, but is mostly used without applying it to an object variable, that types with no prefix like a local and global variable does.
Blockland have some predefined objects. Some ordinary objects could be GameConnection, fxBrickData, ScriptObject and NetConnection. All can be used for an object as an own object, or an inheritance.
To create an object, just follow this piece of code.
new ScriptObject(MyObject)
{
MyObjectVar = "ObjectVariable";
};
This creates an object called MyObject. It contains a string named MyObjectVar. To get that variable, you only have to type the object then a dot, and then the variable.
// Displays "ObjectVariable" in console
echo(MyObject.MyObjectVar);
Namespaces
Attach functions to the object is also easy, but a little bit harder. Just attach a namespace to it.
// Displays the object variable in console
function MyObjectClass::MyObjectFunction(%this)
{
echo(%this.MyObjectVar);
}
This is easier to understand than it looks. First, there is a namespace named MyObjectClass. Then, there is a function, with an argument variable. Instead of use the object name MyObject, you just use the variable argument %this, that already contains the object. This means that even how many objects you use, every object does not conflict with each other.
To link this namespace to an object, the only thing to do is put it in the class variable in the object.
new ScriptObject(MyObject)
{
class = MyObjectClass;
MyObjectVar = "ObjectVariable";
};
And is used like a variable.
// The %this argument is automatically sent
MyObject.MyObjectFunction();
Datablock
A datablock is an object that is specified for graphical information on screen. It could be items, bricks or vehicles. It contains useful functions and variables and makes it perfect to be placed in the game graphically.
A normal datablock could look like this.
datablock fxDtsBrickData(MySpecialBrick : brick2x2Data)
{
category = "My Category";
subcategory = "My Sub Category";
uiName = "My Brick";
};
This creates a brick named My Brick and adds to the brick list. It also uses the already exist object "brick2x2Data" (2x2x1) as an inheritance, gives all information from the inherited datablock to the new datablock.
All datablocks are inherited from namespaces, and the namespaces from them. fxDtsBrickData calls fxDtsBrick namespace functions for example.
Packages and Inheritance
Packages is used to achieve inheritance. Some scripters also use it to reload their script without restarting the server. What you simply do, is placing functions in a package. The package is closed until you activate it.
package MyPackage
{
function GameConnection::onClientEnterGame(%client)
{
Parent::onClientEnterGame(%client);
echo(%client.name @ " entered the game.");
}
};
This is first defining the package MyPackage. Then it is defining the already existed onClientEnterGame, which means that when an user joins the game, this function will call automatically. When it calls, it will call the parent to the function. If no other add-on is using this function, it will take the original function. Thereafter it displays a nice little text in the console.
But this function wont be called at all, before we have activated the package.
activatePackage(MyPackage);
Comments
Comments are used to exclude pieces of code from the script. They are very useful when annotating the code, making it easier for other people to understand the method of action and why certain elements are organized within the script. In TorqueScript, a comment can be expressed by including two forward slashes before a portion of text like so:
//Hello World Script: v1.0
echo("Hello World"); //This displays "Hello World" in the console.
For and While loops
For and While loops are a valuable tool when you need to loop a piece of code over and over again.
For
for(%i = 0; %i < 5; %i++)
{
//Code to run
}
You might be wondering, "What the heck does all that mean?" Well, I'll take you through it. The %i variable at the beginning of the for loop is a random variable, and in this case, it starts off with the value of 0. The next part is the conditional statement, so the loop will repeat as long as %i is less than 5. And the next part changes the %i variable each time the loop is run, and in this case, it adds one to %i each time. An example would be:
for (%i = 0; %i < 5; %i++)
{
echo(%i);
}
This chunk of code would print:
0
1
2
3
4
Not so hard right? Now onto the while loop
While
The While loop is also a useful tool, and the syntax looks like this:
while(Conditional Statement)
{
//Run this
}
Just like in the for loop, we need a conditional statement, the while loop will run the block of code until the condition is no longer met. For example:
%x = 0;
while(%x < 5)
{
echo(%x);
%x++;
}
This will also print:
0
1
2
3
4
References
▪ Appendix A - Quick References. [1].