Friday, August 29, 2008

Thinking Ahead: Design

The last few days have really put a lot of information forward. We know how to handle a lot of different variable: text, number, arrays, local, and global. We know how to pass them to and from different functions. We even know how to use them to determine what the program should do next.
But we still do not know enough to make a game. We really won't for a while yet, but I thought an exercise in what we have learned so far might be a little fun. So that is what we are going to do. We are going to SIMULATE a game in the console window.
First though, we need an idea. That is where thinking ahead comes in. If we plot out enough information into our "Design Document" it will make the programming a lot easier. Soooo...here it goes:
============================================================================
Game Title: Arena Duel
Synopsis: Wally the Warrior and Ralph the Rogue have been friends since they first met at the melee academy. Unfortunately, at the graduation ceremony they both realized that they were in love with the same girl. As part of graduation they must pick an opponent from their class and fight to the death. The winner graduates, and in the case of Wally and Ralph, gets the girl.
Game Play: In this case both Wally and Ralph will be played by the computer. The computer will attempt to make the most of the attack moves available to Wally and Ralph to determine the winner. No maneuvering is allowed in the arena, so movement is not an option.
Output: Text will describe the location, health, and status of each character. It will also describe combat as it progresses until ultimately only the winner remains.
Character Info:
Wally the Warrior
Health: 120
Armor: 100
Dodge: .1
Parry: .1
Attack: 5
Special 1: Shield Stun (Stuns for 3 rounds, 10 round cooldown)
Special 2: Healing Potion (Heals 25 health single use)

Ralph the Rogue
Health: 80
Armor: 30
Dodge: .3
Parry: .2
Attack: 8
Special 1: Bleeding Gash (Target takes 2 dmg per round for 5 rounds. Prevent Healing. 10 round cool down)
Special 2: Healing Potion (Heals 25 health single use)


Order of Events:

=1.) Initialize all variables
= a. Wally
= b. Ralph
= c. Variables for combat processing
=2.) Initiative
= a. Check status. Does it prevent from attacking?
= b. Roll random 0-1
= i. If 0, wally attacks first this round
= ii. If 1 ralph attacks first this round
= c. Call function for first attacker
= d. Call function for second attacker
=3.) Combat
= a. Wally attacks
= i. Is Wally below 60 health?
= 1. No, continue attack
= 2. Yes
= a. Is Wally bleeding?
= i. Yes, continue attack
= ii. No, use potion
= ii. Check cooldown on Shield Stun
= 1. If on cool down, regular attack
= 2. If not on cool down, use stun
= iii. Check to see if Ralph is still alive
= 1. If yes, continue
= 2. If no, declare wally the winner
= b. Ralph attacks
= i. Is Ralph stunned
= 1. No, continue attack
= 2. Yes, pass attack turn
= ii. Is Ralph below 40 health?
= 1. Yes, use potion
= 2. No, continue attack
= iii. Check cooldown on Bleeding Gash
= 1. If on cool down, regular attack
= 2. If not on cooldown, us BG
= iv. Is Wally still alive?
= 1. Yes, continue
= 2. No, declare Ralph the winner
=4.) End Round
= a. Is wally bleeding?
= i. Update character status
= b. Is Ralph stunned?
= i. Update character status
= c. Special ability cooldowns
= i. Decrease shield stun countdown by 1 (if it isn’t zero)
= ii. Decrease bg countdown by 1 (if it isn’t zero)


There we go! Now that is a pretty decent little design document for our little skillset showcase! (please forgive the = signs, it was the only way I could get it to save my formatting in Blogger.)

Tomorrow we will move forward with Arena Duel! Lets see if a few little variables, functions, and if statements can determine who will win the girl!

Thursday, August 28, 2008

Conditional Expressions and if-else statements

One of the cool things about games is that the computer makes decisions based on what it happening in the game. Maybe it is a cooldown timer on a super powerful ability, or maybe it is determining if that NPC should cast a heal spell on itself. How does the computer know to do these things? The programmer used conditional expressions.

Basically a conditional expression is a formula that either produces a True (1) result, or a False (0) result. Torque has a full toolset of conditional operators that you can use to make decisions in your programming:

< Less Than
> Greater Than
<= Less Than or Equal To
>= Greater Than or Equal To
== Equal To (since = is used for assigning variable values)
!= Not Equal To
$= String Equal To
!$= String Not Equal To

Additionally, you can tie two or more conditional expressions together to product a True or False result pertaining to BOTH using:

&& AND (both expressions must be TRUE)
|| OR (either expression must be TRUE)

Lastly, There is an operator that gives you the opposite result (True becomes False and vice versa):

! NOT

So, now we have our ability to tell whether an expression is True or False. But what good is it? Well, you could use it to assign a 1 or 0 value to a variable and then use that variable in a computation. OR, you could use it to set up branches in your program using the if-else statement.

So, what is a branch? Basically you are telling the computer to do one of two things. Its kind of like deciding what you want to do for dinner. Do you have enough money to order pizza? If yes, get on the phone! If not, start making that sandwich.

Translated to if-else, this decision would look like:

if (%money > 20)
{
%dinner = "Pizza!"
}
Else
{
%dinner = "Sandwich."
}

Another cool thing about if-else statements is that you can "nest" them. You can have one inside the other. You put the most limiting expression in the first "if" statement and work your way down to the least limiting. You can also have an else statement for each additional "if".

Using nested if-else statements, we can greatly expand our dinner choices:

if (%money > 10)
{
if (%money > 15)
{
if (%money > 20)
{
%dinner = "Pizza!"
}
else
{
%dinner = "Burger!"
}
else
{
%dinner = "Sandwich."
}

Though this is a little hard to read, it is actually very efficient. If %money < 10, then the program just straight to $dinner = "Sandwich". The rest of the if-else structure is only run as needed. Only if %money > 20 does the whole thing run, and even then the "else" statements are skipped completely!

Wednesday, August 27, 2008

Loopity Loops (or Round and Round We go)

Ok, sometimes actions will need to be repeated a certain number of times or if certain conditions exist. Torque gives us the While loop and the For loop to deal with times like these.

NOTE: do NOT capitalize while and for in your code. Just don't. Trust me.

The While loop is used if we want something to occur while a specific condition exists (hence the 'While' loop). Here is the syntax for a While loop:

while (condition)
{
Commands
}

Your never want to get stuck in a loop. If you do, your program will basically stop responding. You should always ensure that a combination of the condition and the commands gives the program a way to get out of the loop.

Same While Loop:

//wailingWhile.cs
//
function oucheffect ()
{
%playerHP = 1; //gives initial player health
$upHPs = 0; //Initialize %upHPs
while (%playerHP <30) //set the condition for the loop
{
echo ("OMG it still hurts!"); //it is called WAILINGwhile afterall
$upHPs = GetRandom(30); //assigns a random number between 0 and 30 to %healPts
%playerHP = %playerHP + $upHPs;//increase %playerHP
echo ("Player healed for "@$upHPts@". Player health now "@%playerHP@".");//gives us some output to see if the function is working
}
}

Go ahead and try that in the Torque console to see what happens.

The next type of loop is the For loop. Basically this is for when you want an action to occur a specific number of times.

For Loop syntax:

for (initial value; state check; update value)
{
commands
}

Here is a simple module using a for loop to print a specific amount of random numbers:

//rndfor.cs
//
function countem ()
{
for (%counter = 1; %counter <= 10; %counter++)
{
Echo(GetRandom(10));
}
}

Give that one a try as well. Always remember: when coding, for and while are not capitalized. It will generate a parser error that will have you looking for the mistake for hours. If you don't know 100% that it should be uppercase, use lower. In my experience so far it is safer.

Tuesday, August 26, 2008

Setting up Torque

Before we go any farther, it would be nice to be able to test our modules and functions to make sure they do what we think they do. If you haven't yet, go ahead and download the latest version of the Torque Game Engine (TGE) from Garage Games:


Download TGE HERE


One you have installed TGE you should have a folder named TGE_1_5_2 or something similar. Unless you know C++ already, you are going to have a ton of extra files that you won't really have a use for right now. The folder we are most interested in is under that one TGE_1_5_2\Example\

Under that folder go ahead and create a directory called "Test". This is where we will put all of our modules before we try them out.

Now, go ahead and double-click torqueDemo.exe. This will start Torque and allow us to test our modules. Once Torque is open, open the console window by hitting the "~" key. The "~" is your friend. Trust me.

Ok, so lets make something to test. Open notepad.exe or another text editor and create a new document. Then, type in the following module. You will need to save it as type "all files" or "*.*" and name it takedamage.cs and save it to the TGE_1_5_2\Example\Test folder you just created.

Since yesterdays module covered a lot of territory, lets go ahead and use it as our example:

//takedamage.cs
//reduces health after being hit or falling

function healthtracker()//main function doesn't need an arguement
{
%playerHP = 100; //initializes player health at 100

echo ("Starting Player HP ="@%playerHP); //prints the players current health to the console

%playerHP = take10dmg (%playerHP); //calls the function "take10dmg" and passes the players current health as an argument
echo("Player HP after fall ="@%playerHP);//current health to console

%playerHP = take10dmg (%playerHP); //calls the function "take10dmg" and passes the players current health as an argument
echo("Player HP after hit ="@%playerHP);//current health to console
}

function take10dmg (%playerHP) //create the new function. Can use the same variable since it is local
{
%playerHP = %playerHP-10; //reduce HP by the stated amount
return %playerHP; //passes the arguement back to the calling function
}

Once you have it typed in (or cut and paste) and saved as takedamage.cs open the console window in Torque and type in: exec("/test/takedamage.cs");

Make sure to use "/" and not "\" inside of Torque.

Once you type that, Torque will load and compile your module. If you make any changes you will need to reload the module before Torque sees the changes you have made.

Next type: healthtracker

And the function should run and you should see what happens to %playerHP when they take damage.

Intro to Torque Moduals and Functions

Ok, so now you know about variables. But where do you put them? I suppose you could enter them in through the console window but that wouldn't be very efficient and you couldn't exactly create a game that way.

Well, to get your commands and information into Torque you need to create Modules. If you look through the folders under the Example directory you should see a bunch of files with .cs at the end. These are your modules and they are what is going to make your game YOUR game.

main.cs is the first torque script file that the engine will try to load. This file will be in the same folder as the executable. Go ahead and open it up and take a look around.

Most modules will use a header that describes what the file is:

//main.cs
//Main module for the Torque Game Engine

After that, the module will be broken up into functions. Functions are where the real work occurs inside of the program and look like this:

function Take10Damage()
{
//commands, variables, etc go here
}

You will notice that there is no ";" at the end of these lines. It is not required and will give you a syntax error when it is run in Torque. After the function is declared, a "{" marks the beginning of the function and a "}" marks the end of the function.

So why use a function at all? Why not put everything into one big file? Because functions can be made very flexible and multi-purpose. Lets say that our player is hit with a rock and then falls off a cliff. If both are supposed to cause 10 damage to the player then a single function can be created and called by both to decrease the players health.

So you may be asking yourself how do you get values from one function to another. Well, one way is to use Global Variables (ones that start with $). Another way is to pass an argument. The () at the end of the function declaration is not just for looks. You can use it to pass any amount of useful data into the function. Lets take a look at the following module:

//takedamage.cs
//reduces health after being hit or falling

function healthtracker()//main function doesn't need an arguement
{
%playerHP = 100; //initializes player health at 100

echo ("Starting Player HP ="@%playerHP); //prints the players current health to the console

%playerHP = take10dmg (%playerHP); //calls the function "take10dmg" and passes the players current health as an argument
echo("Player HP after fall ="@%playerHP);//current health to console

%playerHP = take10dmg (%playerHP); //calls the function "take10dmg" and passes the players current health as an argument
echo("Player HP after hit ="@%playerHP);//current health to console
}

function take10dmg (%playerHP) //create the new function. Can use the same variable since it is local
{
%playerHP = %playerHP-10; //reduce HP by the stated amount
return %playerHP; //passes the arguement back to the calling function
}

I am sure you can imagine the flexibility of a tool like functions and passing arguments between them. I know this seems like a lot of messing around after all, where are all the cool graphics and effects? Don't worry, those will come in time. For now we have to lay the ground work for where we are going to end up. And that is hopefully with a fun, playable game.

Monday, August 25, 2008

Starting with Torque: Variables

For a computer to make decisions it has to have data. This data could be about the number of Hull Points a Starcruiser has, or it could be the players name. For this data to be useful it has to be stored in a useful manner. That is to say, Torque must know where to find that information. The answer to this is variables.

Torque script is a little different than other languages. You do not have to define a variable before you use it. Additionally, there are only a few types of variables and they are not dependent on the type of information stored.

Examples:

$hullPoints = 100;
$playerName = "Lucifer";

The engine knows just how to treat each variable depending on the context.

You will notice that the variable name started with "$". This marks it as a Global Variable. You can use this variable in any function and its value will carry over into any other function. If the variable started with "%" it would be a Local Variable. The value stored for that variable could only be used inside of the function in which it is created.

Data will usually need to be manipulated in some way. Otherwise, why bother having it? Number can be added, subtracted, or any other standard form of calculation in the following way:

$hullPoints = $hullPoints - 1;

Another way to subtract (or decrement) by one is:

$hullPoints--;

You can also increment a variable by 1:

$hullPoints++;

You can also decrement, increment, divide, or multiple by arbitary numbers using the following formulas:

$hullPoints += 10; //increments by 10
$hullPoints *= 2; //multiplies by 2

(Side note: using "//" marks whatever follows it as a comment. Torque ignores anything after the // until the next line.)

Text variable work a little differently. After all, you cannot multiply or divide by a line of text. To put two text variable together we use the "@". Here is an example:

$firstName = "Tom";
$lastName = "Beauchamp";
$fullName = $firstName@" "@$lastName;

If we were to print out the value of $fullName it would give: Tom Beauchamp.

Since Torque recognizes the context that a variable is used in, we can also do this:

$firstName = "Tom";
$lastName = "Beauchamp";
$Age = 36;
$personalInfo = $fullName = $firstName@" "@$lastName@" is "@$Age"@" years old.";

If we were to print out the value of $personalInfo we would get: Tom Beauchamp is 36 years old.

Another way to determine a value is using a boolean expression. Boolean expressions always equal either True (1) or False (0). The number value is what will be stored in the variable.

Example:

$firstAge = 36;
$secondAge = 31;
$isolder = $firstAge > $secondAge;

This last example is the perfect time to talk about storing multiple pieces of the same type of data. What if we had 20 ages to store? Would we want to create 20 separate variable that we then have to keep track of?

No, and luckily we do not have to. This is why Torque Script allows the use of arrays. Instead of creating $firstAge through $twentieth age we can do the following:

$ages[0]=36;
...
$ages[19]=31;

One thing about arrays: The first index position in an array is always 0 and the last is always 1 number less than the total in the array. So if an array has 20 positions, then the last one is 19.

Arrays are very handy for storing large amounts of similar data. When we get to loops they will come in very handy and save a lot of coding time.

If you have any questions, or see any mistakes please let me know at we4ponsgr4de@gmail.com

What is Torque?

The Torque Game Engine (or TGE) is a professional grade 3D engine for building the backbone of just about any type of game you want. Here is what Garage Games has to say about their product:

"TGE has everything you need out of box to make any genre of game. You can create games for the PC, Mac, and Linux, with a porting path to popular consoles such as the Xbox 360 and Wii. The 3D Toolset allows you to create game worlds on the fly, for a real-time editing experience. Couple all this with the award-winning TorqueNet client/server architecture for multiplayer games, the GeoTerrain system for large worlds, and the Torque Lighting Kit for realistic scenes, and you've got a complete development solution."

Sounds simple, right? However there are a few of caveats:

1.) You have to know how to code.
2.) You may have a game idea, but do you have a DESIGN?
3.) You need content for your game.

Still here? Good, because though they may seem like a lot, they are pretty easy to overcome and here is why:

1.) Just about anything in the game can be modified using Torque Script. It is similar in form to C++, but not near as complex. Plus, the heavy duty graphics and networking work is already done for you.

2.) If you've got an idea, you have proven that you have the imagination to design your game. Just keep a pad and pencil handy and before you know it you will have your design document in hand.

3.) There are a few way to get content into your game. The first is to make it yourself. Milkshape an amazing and inexpensive tool for making high polygon models. The second is to buy models online. Some packs are expensive, some are cheap. Just be aware of what you are getting. Lastly is to find free models. Several websites offer models ranging from rocks and trees to hyperspace-capable battlecruisers. Just make sure that you follow whatever licensing agreement they offer.

Here are some links to get your started:

Torque Game Engine by Garage Games (Free Demo)

Milkshape by Chumbalumsoft
Free 3D Models from 3DXtras.com