Tuesday, November 18, 2008

Debugging

So while the thief game under goes some planning, I decided to finish up an old script I had from back in the A5 days, a silly game called "TANKS!"

Well, the game's programming is really simple and a good amount of it has been scripted, it just isn't in Lite-C yet.

And there I was trying to get a health bar to show up on the screen. The way a health bar works is that it's size_x (horizontal size) is affected by a percentage of the players health. So to get this percent, I defined a skill and called it "maxHealth." MaxHealth defaults (allegedly) at 100. The code looked like this:



#define distDown skill6
#define bottom skill7
#define maxHealth skill8

//..more variables and other things that do not affect maxHealth

action pTank()
{
var engSnd;
wait(1); //wait for the first frame for c_setminmax
c_setminmax(me); //set the bounding box
set(my,FLAG2 | SHADOW | CAST | METAL); //set some flags
player = my; //set the point
my.health = 100; //set health to the default 100
my.maxHealth = 100;
turret = ent_create("tankturret.mdl",my.x,pTurret);
//... code continues, does not use my.maxHealth after this


function initScreen()
{
while(!player) { wait(1); } //wait for the player to be loaded
set(healthBar,VISIBLE | LIGHT); //turn on the health bar and allow it to be set by RGB values
vec_set(healthBar.blue,vector(0,200,0)); //health bar is green
while(player) //while the player exists
{
healthBar.size_x = 190 * (player.health / player.maxHealth);
wait(1);
}
}


function initScreen() sets up the GUI and places a health bar where you can see the part divided by total formula being used to make the healthBar.size_x proportional to the player's health.

After putting this together, I got an empty pointer crash. After I fixed that with a wait(1) instruction, everything was great and dandy, except the healthBar was not showing up on my screen.

So I thought maybe the while condition is for some reason not true. I stuck "beep()" in initScreen in several places and did several test runs. What beep() does is it plays a sound so it is an easy way to test code.

They beeped.

I thought maybe something somewhere is setting the VISIBLE flag on the healthBar off. I wrote a quick function:


if(is(healthbar,VISIBLE))
{
beep();
}


It beeped. I had a health bar that was visible. Its flags were correct, in fact, the flags were the same exact flags as I have set on a health bar in a different project, a health bar that works. The while conditions were good. There was no reason why the bar wasn't showing up. None.

And then I thought, maybe its the equation itself, the "healthBar.size_x = 190 * (player.health / player.maxHealth);"

I used diag_var() in here to get the engine to write down what the size was.

And what I got astonished me.

-317.

The scale was a negative number. Then I looked at player.health.

The diagnostic spit 100 at me.

Then I looked at player.maxHealth

The diagnostic spit a negative number that made no sense.

Looking at the code I posted at the beginning of this post, I could not see what it was. player.maxHealth was set to 100 and that was the only place where I set it equal to anything. There was no other point in the script where it was used.

So I decided to try a global variable rather than a skill. I called it "pMaxHealth." I set that to 100 and put it in place of "player.maxHealth" in function initScreen().

And the bar worked.

And then it hit me.

I looked at skill7, above player.maxHealth, the one called "bottom."

Bottom is used here:

vec_for_min(my.bottom,me);

That one line of code finds the bottom of an object and returns a vector. my.bottom was now a vector. In 3D graphics, vectors have 3 parts, x,y,z. If you define a skill and use it as a vector, the following two consecutive skills become the y and z components. skill7, bottom, was a vector, and thus skill8 and skill9 were parts of that vector. And so maxHealth, which was skill8, was in fact being modified by the vec_for_min instruction, which came after its assignment of "player.maxHealth = 100;"

So the whole issue was fixed by changing maxHealth to skill 11.

I guess breakpoint was a good name for this blog. There are so many things that can go wrong.

while(thisCodeDoesntWork)
{
smashComputer(); //take out some pent out anger
throwDartsAtBoss(); //take out more anger
sleep(6*60*60); //sleep six hours
}

2 comments:

Anonymous said...

Hi just wanted to say that thanks to your blog on debugging, I finally figured out why my own 3d gamestudio project keep returning me empty string for player position.

I actually have to:
wait(1);
player = player object
before I can use the parameters...

Thanks!
Wraithrune
wraithrune at yahoo dot com

Anonymous said...

Hello;

can you programm a website like skill7.com?

regards