ThreeFingerPetes Lessons and tips on programming part 2

Talk about making games.

ThreeFingerPetes Lessons and tips on programming part 2

Postby Fuzzy » Thu Mar 09, 2006 10:24 pm

I want to show you a way to speed up your own code, at the expense of program size. I know the bigger problem people have is huge GE games, so I will cover that another time.

In any case, you might see an oportunity to do just the opposite of what I outline here, and that will help you with game size.

Ok. the situation is that you need to create 10 actors, all in a row.

You create the prototype actor, select that he is not to show up at game start, and create a variable to keep count.

Next, you select a key down event, put it as space bar, and no repeats. This is just to test it.

In the key down action, you go to script editor, and put

Code: Select all
for (count = 0; count < 10; count++)
{
    CreateActor("blah", "icon", "no parent", "no path", count*32, 0, false);
}


You see that first line? All sorts of interesting stuff is happening in it. Basically, that line contains three commands.

Here is what it does.
1. It sets count to equal zero. (count = 0)
2. It checks to see if count is still less than ten. (count < 10)
3. It executes your create actor action, once, as long as count is less than 10.
4. it increases the value of count by 1. (count++)
5. It goes back to step 2.

As you can see, your create line only gets 1/4th of the time share of the code. 75% of the time it is doing various tasks to keep the numbers in line. If you needed 100 actors, its no more efficient.

So to make this more efficient, we do whats called "unrolling the loop". This is a combination of what a newbie would do, and what I showed you above.

Lets change the situation a bit. Now you need 100 actors. We will make 10 rows, ten columns. We could do nested loops, one inside another, but this way is going to squeeze a little speed at the expense of size.

Unrolling the loop means doing some of the work by hand, and then letting the compiler do the rest.

We still set up the for loop, but this time we just do 1/10th of the lines the newbie way.
Code: Select all
for (count = 0; count < 10; count++)
{
    CreateActor("blah", "icon", "no parent", "no path", count*32, 0, false);
    CreateActor("blah", "icon", "no parent", "no path", count*32, 1*count*32, false);
    CreateActor("blah", "icon", "no parent", "no path", count*32, 2*count*32, false);
    CreateActor("blah", "icon", "no parent", "no path", count*32, 3*count*32, false);
    CreateActor("blah", "icon", "no parent", "no path", count*32, 4*count*32, false);
    CreateActor("blah", "icon", "no parent", "no path", count*32, 5*count*32, false);
    CreateActor("blah", "icon", "no parent", "no path", count*32, 6*count*32, false);
    CreateActor("blah", "icon", "no parent", "no path", count*32, 7*count*32, false);
    CreateActor("blah", "icon", "no parent", "no path", count*32, 8*count*32, false);
    CreateActor("blah", "icon", "no parent", "no path", count*32, 9*count*32, false);
}


Now most of the time is spend creating actors, and a smaller percentage is spent counting.

But ThreeFingerPete! Isnt it better to do this?

Code: Select all
for (xcount = 0; xcount < 10; xcount++)
{
    for(ycount = 0; ycount < 10; ycount++)
    {
         CreateActor("blah", "icon", "no parent", "no path", xcount*32, ycount*32, false);
    }
}


And I say, yeah, in lots of situations, thats what I would do. Its smaller, if not so easy to read nested loops. But is it faster? No way. you might not notice with 10 actors, but you would with larger numbers.

Think before making the compiler work. You know for a fact that you need 10 actors in a row, so why should your game waste effort doing it all over again? If something like this were put in an actors draw event, your game would bog right down.

In my next lesson, I will show you how to avoid some if statements. You may even figure out a way to avoid fors and whiles.

In the lesson after that, I will show you how to make that my mess tiny again. It will be something you will not want to do until you are ready to package your game, because it will make it very unreadable.

Please post comments and point out any errors in my code... I want to hear from you all.
Last edited by Fuzzy on Sat Mar 11, 2006 2:53 pm, edited 2 times in total.
Mortal Enemy of IF....THEN(and Inspector Gadget)

Still ThreeFingerPete to tekdino
User avatar
Fuzzy
 
Posts: 1068
Joined: Thu Mar 03, 2005 9:32 am
Location: Plymostic Programmer
Score: 95 Give a positive score

Postby mrdark7734 » Fri Mar 10, 2006 4:12 am

Very nice, and very concise. Keep up the good work.
User avatar
mrdark7734
 
Posts: 21
Joined: Thu Aug 25, 2005 12:49 am
Location: Texas (where we're crazy enough to shoot a president)
Score: 0 Give a positive score

Postby Novice » Fri Mar 10, 2006 11:15 pm

I like what you are trying to do, most of the topics cover the basic of programing in GE and it is quite refreshing to see some good tips and tricks. Keep up the good work!
Why do i always get stuck?
User avatar
Novice
 
Posts: 399
Joined: Mon Aug 29, 2005 10:54 am
Location: Relative
Score: 5 Give a positive score

Postby Fuzzy » Sat Mar 11, 2006 3:21 pm

ok. I think its time to do part 2... If I dont get it done, I will return and finish later. Thats a joke. Its very short, and very simple. I wouldnt be surprised if most of you know this already.

This part deals with eliminating the use of if statements, and maybe some rare for()s and While()s. I covered this once before, but I feel its time to go over it again. and Collect it in one spot.

As before, we will set up a test situation that you can try out if you are inclined.

Create an integer variable called something like Status. Always be careful not to use names that GE(or any language) reserves for its own use. that could make a very nasty error.

Select your test actor, and then select its create actor event. From there go to script editor. enter this line of code.
Code: Select all
Status = 1;


Thats it. One line. close the script editor, and the create actor event.

Now... open your actors key down event, and select the space key(or any key), and no repeats. Hit the action Button, and select script editor.

Enter this HUGE mess of code.

Code: Select all
Status = !Status;
VisibilityState("Event Actor", ENABLE);


What the first line does is to tell GE to flip the value of Status. the ! means 'not'. Not 1 is Zero.. sort of. You could also set Status to be Zero and it wil end up being equal to 1 when you flip it. The Flip is where the magic is, because it kills the need for testing the variable. THink of using a light switch. on... or off.

You can type out the second line or find it in the functions list. THis is how it will appear. We need to make a change. Change where it says ENABLE to Status or whatever you called your variable.

Here is how you would normally see that done.
Code: Select all
if (Status == 1)
{
    VisibilityState("Event Actor", ENABLE);
}
else
{
    VisibilityState("Event Actor", DISABLE);
}


You can see that we saved a good deal of typing, avoiding using a lag inducing if() statement(my Mortal Enemy defeated again! Hurrah!), and made it a good deal neater too.

So thats pretty simple, but it can be spiffed up and used for more complicated things.

For example, say you wanted to make an rpg, and at times, you wanted to avoid damaging a character, like in a cut scene with monsters. Rather than disabling all the damage code, or using duplicate actors, just use this trick as a multiplier for the damage.

Code: Select all
Hp = Hp - Enemy.Damage*Status;


Dont use that exact line! Its a terrible way to handle Damage. It would let you go into the negative Hit Points.

Thats it. If you can think of some creative uses for this trick, share it with all of us ok?
Mortal Enemy of IF....THEN(and Inspector Gadget)

Still ThreeFingerPete to tekdino
User avatar
Fuzzy
 
Posts: 1068
Joined: Thu Mar 03, 2005 9:32 am
Location: Plymostic Programmer
Score: 95 Give a positive score


Return to Game Development

Who is online

Users browsing this forum: No registered users and 1 guest