Sunday 28 September 2014

Degbugging by Logging



In this blog I will talk about how we log.

So what logging am i talking about?

No I'm not talking about activities to do with tree trunks but the recording data occurance. 
Logging data acts just like how many business uses a book or chard to record business transaction, or black boxes record the flight data of planes. Logging code will generally save code to a specific file, but it can also help with debugging by printing it to the console. This can help by saving test data, or helping identify how code crashed. 


So how can we do this (in c++) ?

In c++, the language I mainly code in, there are 2 different ways of doing it std out, std err. Both of these generally uses Std in to get input from the keyboard, unless there is another 3rd party library. Std stands for standard library for those who are wondering.
·
  •   STD out, this is a simple output, which can saved in a file or outputted the console. This is a buffered output, which means it will save to a buffer until it gets full, or flushed, which is when you tell it print. With this buffer you can save a lot to the buffer before printing it, making it a good for variable checking. The issue with this is that if the game crashes, or has a break point, right before the std out, it will not print.
  •   STD err, err standing for error, this is a different output, which isn't buffered. This is because it will always print whenever it is called. This is good for unstable code, so that you can print out the error type when ever the code crashes.

Debugging Tip: Assert() is a useful function which doesn't log but will help with debugging. It will crash the program when the specific conditions are meet. For example if you want to make sure the player will always stay below a specific speed. This could be due to the fact the player will clip through objects if he is too fast.
Asset (player speed<100);

 

How to define a good logger 

 In class we defined a lot of definitions for what should consist of a "good logger". The following 4  points where the teacher agreed were most important through out the discussion. There are many agrueable good features left out, so feel free to add them to your debugger.
  1.  The first thing you should do for a good logger is that if there is a logger class, it should be template and a singleton. Whenever a class needs it, it should get a reference to the singleton object. This is the correct way rather than just have everything inherit from it and create other instances of the class. 
  2. The second thing is that the logger should have some ability to print the data being outputted/recorded to the screen. This is quite useful when monitoring constantly modified variables, such as player position, speed, or health.
  3. The third is the priority or level of the bug which has occurred. With your logger you should be able to define the level of the bug which you have just encountered. With this the bug can be
  4. Be able to specify a variable to track with the logger. The current value of the variable will be tracked every frame, recorded and/or outputted when specified.
With a logger at your disposal when creating a game/ debugging a project, it can help drastically. This can help identify problems early or solve existing ones 

Saturday 20 September 2014

A (bug) blast from the past

Its the beginning of a new school year and the beginning of a whole new set of technical blogs. For this semester's technical course, we have Advanced debugging, with the program's well respected teacher. In this course, we look at ways to solve bugs of any sorts, high and low level, memory leaks, wrong memory allocation and sorts.


To start off this year, I wish to go back and discuss a simple but yet deadly bug which took place during object deletion. This was second year when I was creating my bullet hell game, Bullet Devil, and was creating my own mangers with std::vectors. Theses vectors contained pointers to objects which were being managed, bullets in this case, which could be modified by the manager. The bug occurred when I was deleting bullets with my manager, with the following code.

            if (BulletVector.at(i)->    b_hit==true)//true
            {
                BulletVector.at(i)->~Bullet();// calls the bullet
                BulletVector.erase(i);// erases that object    
           }    



The problem was that the bug would trigger after a random number of bullet destroys, sometimes after 5 bullets, sometimes after 20.  The visual studio disassemble wouldn't help either, directing me to the spot where I knew was the issue.

The solution came when a good programming friend of mine came to help point out what was the issue with this was.The problem was that next iteration of the loop will increase the variable i, but there was also an element removed. This means everything after the deleted element has moved back one step, but the i variable will be 1 element ahead.
To fix this everything in the array after the removed element, we simple decrement the i variable by 1. So if the i variable increases AND things moved backwards, the i variable will not skip any elements. 

The following code fix was:

               BulletVector.at(i)->~Bullet();
               BulletVector.erase(BulletVector.begin()+(i--));// erases that object
               continue;


From this point on, when ever I made a bullet, powerup and enemy manager, for c++, I always included this segment of code.