Previous: Model Animation

Global variables. Local variables.

If you have read the second workshop (the one that talks about variables) you might wonder why we haven't covered global and local variables there and then. Are these concepts so difficult to understand for a beginner?

Fear not, for you have used global variables all this time without even knowing it. I needed to explain actions and functions first, because we need them in order to understand how local variables work. Let's fire up an example; start Lite-C, open workshop22 and then run variables.c:

It looks like a post-apocalyptic version of our planet indeed! I have used a black, empty level and I have placed an earth model inside it:

var rotation_speed = 0.1;


function mother_earth()
{ 
    while (1)
    { 
        my.pan += rotation_speed * time_step;
        wait (1); 
    }
}

function main()
{
    vec_set(sky_color,vector(1, 1, 1));   
    level_load ("");
    ent_create("earth.mdl", vector(400, 0, 0), mother_earth);
}

Now that's what I would call a nice script file! The sphere model changes its pan angle by adding "0.1 * time_step" to it every frame, because "rotation_speed" is set to 0.1. This is, as you might have guessed, a "global" variable, a variable that is defined outside any action or function. Like I said, we have defined only global variables in all the previous workshops without even knowing it! Now run the level again, press "Tab" to show the console and type in the following line of code:

rotation_speed = 5;

The sphere rotates a lot faster now, right? (If it doesn't, you didn't type in the code properly). We can control the rotation speed using the console because the variable named "rotation_speed" is known to each and every function or action, including the built-in engine function that displays the console. That's how a "global" variable works!

A "local" variable is known only inside the action or function that includes its definition. Let's turn our global variable into a "local" variable; move the line that defines "rotation_speed" inside the action named "mother_earth":

action mother_earth()
{
   var rotation_speed = 0.1;
   while (1)
   {
     my.pan += rotation_speed * time_step;
     wait (1);
   }
}

Now let's run the script file again:

The planet rotates just like before; let's type the same line that changes the speed at the console:

rotation_speed = 5;

This time the rotation speed hasn't changed at all! The console function doesn't know the variable anymore, because "rotation_speed" is now a local variable, so it is known only inside the action named "mother_earth". No other function has any access to it.

So what good are local variables for? Why don't we use only global variables? Open and run variables_2.c:

We have got two rotating spheres now, and each one of them uses a different rotation speed! When we look at the code, the first thing we notice is that we've created both spheres in the main function, and both of them use the same action:

///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////
function mother_earth()
{ 
    var rotation_speed = 0.1;
    if (my.y < 0) 
        rotation_speed = 20;
    while (1)
    { 
        my.pan += rotation_speed * time_step;
        wait (1); 
    }
}

function main()
{
    vec_set(sky_color,vector(1,1,1));    // black sky
    level_load ("");
    ent_create("earth.mdl",vector(400,-100,0),mother_earth);
    ent_create("earth.mdl",vector(400,100,0),mother_earth);
}

We have defined a local variable named rotation_speed inside the function named mother_earth. For the left sphere, rotation_speed has a value of 0.1, and for the right sphere the same variable has a value of 20. Our mother_earth action is called twice, once from the right and once from the left sphere. So two different, independent copies of mother_earth are running at the same time, and ever copy uses its own set of local variables. Let's take a look at the beginning of the action:

action mother_earth()
{
    var rotation_speed = 0.1;
    if (my.y < 0)
        rotation_speed = 20;

The right sphere was placed at y = -100, so for the right sphere the "if (my.y < 0)" comparison is true and rotation_speed is set to 20, while for the left sphere the comparison is false and rotation_speed isn't changed, continuing to be 0.1. These two "rotation_speed" local variables don't interfere with each other at all, even if they have the same name and even when they are contained in the same function.

Now don't get me wrong, I like global variables too! They are necessary whenever some data must be available for every action or function! Want to have all the monsters in your game do a little dance when the player dies? Then you'd better make player's health a global variable, because the monsters will want to check its value from within their own actions or functions! On the other hand, you will want to use local variables for all the instructions that only take place inside a function or action: animation, movement, and so on.

 

Next: The Bones Collector