12/18/09

I'm a lumberjack and I'm ok!

I had another busy night of game development last night. The new feature of the night was to add a logger to my engine.  I had 3 requirements for my logger:
  1. I need to be able to create multiple instances of the logger so I can create log files for each area of my engine.
  2. I need to be able to differentiate between normal debug messages and error messages when I'm reviewing the log.
  3. I need to be able to disable logging across the system at compile time.
With these requirements in mind, I created a pretty simple logging class that is easy to use and gets the job done.
class Logger
{
    //Fields
    FILE* file;  //File the log is saved to

    //Methods
    void CloseFile(); //Closes the logging file
public:
    //Constructor/Destructors
    Logger(){file = NULL;}
    ~Logger();

    //Methods
    bool OpenLog(char* filename);     //Opens the log with the given filename
    void Write(char* msg, ...);       //Writes a normal message to the log
    void WriteError(char* msg, ...);  //Writes the message to the log and flags it as error
};
Nothing too earth shattering here.  To use the logger, create an instance then call OpenLog with the filename of the log file you want created.  One note you need to make here is that if you are creating files in another directory make sure that directory exists.  C++ won't create the directory for you if it doesn't.

I'm rather proud of the write methods.  As you can see they use variable arguments which is something I've never done before.  This will allow me to use formatting in the messages I send to the log, instead of either having to create the formatted message before I send it to the logger or adding a write method for every combo of parameters I need.  Here are the guts of  Write:

void Logger::Write(char *msg, ...)
{
#ifdef LOGGING_ON
    //Get the variable arguments
    va_list listPointer;
    va_start( listPointer, msg );

    //Get the current time
    boost::posix_time::ptime t(boost::posix_time::second_clock::local_time());
    std::string time = boost::posix_time::to_simple_string(t);

    //Write time

    fprintf(file,"[%s] ",time.c_str());

    //Write the msg
    vfprintf(file,msg,listPointer);

    //End the line
    fprintf(file,"\n");

    //flush the file
    fflush(file);
#endif
}
WriteError is almost exactly the same except it adds "Error!!!!!!" to the message so you can differentiate error messages in the log from normal messages.  The key to the whole operation is vfprintf.  This method allows me to just pass the va_list right in without caring what's actually in it.  Also you can see that I'm checking for the definintion of LOGGING_ON.  Commenting out that defininition which lives in Logger.h will turn off logging system wide at compile time.

The one area where this logger fails is that it is not thread safe.  If I ever did plan on adding multiple threads that wrote to the same log file, this wouldn't work very well because there exists the possibility that the two threads would be writing to the log at the same time causing some jumbled log messages.  Right now I don't plan on adding multi-threading to my engine, but if I do, I'll need to revisit this.

Now that I have logging in place, my next step is to come up with a consitent and elegent way of handling exceptions.  This probably isn't going to be a new class that I write, but instead a standard for how I write all code.  I've got a little research to do, but as always, I'll let you know how it goes.

References
Here are some thinks to sites that helped me develop the logger:

12/14/09

Boosted spirits

I added boost to my solution this evening and surprisingly it went rather smoothly. No major hiccups to speak of tonight. It appears that my C++ solution skills are becoming ninja like! Well maybe not quite to that level, but I certainly am more versed in it than I was just a couple weeks ago.

As part of my inclusion of boost, I modified the ResourceManager so that it uses shared pointers instead of actual pointers. This is going to solve the major flaw I had that really prevented me from handing out the same resource twice without fear of one of the copies being destroyed. Now the smart pointer will handle all the freeing of resources.

The next task I have in mind is to handle logging and exception handling. I don't want to get too far into development without these two in place. I haven't read to much into best practices as far as logging and exception handling in games goes, so I've got some research to do. I'll post links to whatever I find on the subject in my next post which should hopefully cover how I implemented the system.

Resource Manager

I've created my first major piece of functionality for my game engine. I added a very simple resource manager which will be responsible for loading all games assests into memory and then distributing them upon request. As I wrote in my previous post, I originally wanted to create a resource cache, but I realized that was going to add a lot of overhead for something that in the end I probably wasn't going to need since the games I'll be making with this engine are probably not going to be very rich in assets. That being said, I don't think it would be terribly difficult to convert into a resource cache if I ever wanted to go that route.

So lets get into the meat of it. My resource manager consists of two classes, Resource and ResourceManager. The names pretty much give away their purposes. Resource represents a single asset that has been loaded into memory. It holds the asstet's raw data along with a filename and the size of the asset.

ResourceManager does most of the heavy lifting. It takes in a zip file or a single file and creates Resources from them. The pointers to the Resources are stored in two std lib containers, a map and a list. Each container has its dedicated purpose. The map is used for random access of the Resources using the Resource's filename as the key. The list is used for looping through the resources. Right now the list is only being used in the destructor of the ResourceManager when it releases all of the resources. If I ever wanted to convert this to a ResourceCache, the list would play a much greater role by becoming a sorted list of assets ordered by last use.


The major flaw I have in my design right now is I store and handout regular pointers to a resource. This becomes a problem when I hand out the same resource more than once and one of the recipients releases the resource. All other pointers to that resource become garbage because the memory that the resource pointer pointed to has been released. This leads me to my next task, adding boost to my solution.

In Game Coding Complete they use boost's shared pointers extensively to solve this exact issue. The shared pointers will allow me to hand out multiple copies of the same resource without worrying about resources being released prematurely because the shared pointer keeps track of references to itself and won't release memory until all resources have been released. I've read a little on using boost and I've heard that it isn't the easiest thing to add to a solution, so wish me luck.

12/4/09

It's me again

Long time, no blog. I got a new job as a work at home web developer and that's been taking much of my precious game development time. I'm finally starting to get back into the groove of things now that I've pretty much figured out how my work schedule is going to go.

I'm back working on the TetrisClone project. I haven't made many strides since my last post, but I have a game plan that I'm hoping will lead me to the completion of this project. The first step of my plan is to get a solid base in place. Something that I can possibly use on other games. Some may even call want I'm creating an engine!

I've started work on the resource manager which will handle all the loading and passing out of game assets that must be loaded off of disk. I'm drawing a lot of inspiration for my engine from the book Game Coding Complete 3, and the resource manager is no different. I had originally planned on creating a ResourceCache like they have in the book's source code, but in favor of time, I've decided just to create a ResourceManager that will hold all the game assets needed in memory for as long as they're needed. I figure the games I'm going to be creating will be small enough to allow me to do this and it will save me from having to debug a cache.

I've started off by adding the zip file importer from Game Coding Complete, slightly modified, but mostly intact, to my project. Again, I had aspirations to write my own zip file importer, but for the sake of time, I decided to borrow (giving the proper credit in the source of course).

Just copying the code from the GCC source to mine wasn't enough though. Again, as I delv into the depths of c++, I ran into some issues that I wasn't anticipating. The zip reader from GCC uses zlib(http://www.zlib.net/) to do the heavy lifting. It uses a 3rd party .lib file which I've never used in c++ before. It wan't too hard this time to figure out what I needed to do though.

First I created a new Libs folder to hold this library file and future ones if needed. I then went into the properties of my executable project and added the new directory to "Addition Library Directories" under Configuration Properties>Linker>General. Then I added zlib.lib to Additional Dependencies under Linker>Input.

It seems like I'm having much more trouble with setting up projects properly than I am getting the code to work. I guess I'll learn as I go on that front. I haven't seen too many books or articles describing how to set up vs in depth.

Now that I can read in zip files, it's time to move on to the meat of the operations, the resource manager. Hopefully I'll have this done and have all the details of my adventures soon.

10/21/09

The first step is always the toughest

Well, I'm finally off and running on my game project. I've decided to create a Tetris clone, because I don't want to deal with any major game design, I just want to create a well polished game. A Tetris clone will let me do that since there are already well established game rules for Tetris allowing me to focus more on programming than game design.

My first step for creating this game was to set up a new solution/project in visual studio and get an app that simply creates a window and draws a blank screen using directX. I've always had problems starting a game project and this one is no exception. Figuring out which libraries need to be linked and what properties need to be set for each project has always given me fits.

I'm trying to create a solution where most of the base game functionality is stored in one project, while the game specific stuff is stored in another project. This was the source of most of my frustration. I've never created a multi project C++ solution before, so I was getting linker errors all over the place when I was trying to use a class from GameBase in my TestrisClone Project. After much research I figured how to get the two projects to play nice:
  1. Make sure the base project outputs a .lib and not a .exe. To do this right click on the project and select properties. Go to Configuration Properties -> General -> Configuration Type and change it to Static Library (.lib)
  2. Now you need to tell the game project where the base project is so it can include the headers. Right click on the game project and select properties. Go to Configuration Properties -> C/C++ -> General -> Additional Include Directories and add the directory that contains the files you want to include, in my case ..\GameBase
  3. You also need to point the game project to the game base library. Open the properties again for the game project and go to Configuration Properties -> Linker -> General -> Additional Library Directories and enter in the directory where the .lib file is created, in my case it was $(OutDir)
  4. Finally you need to set up the solution project dependencies so that the projects build in the correct order. To do that, right click the game project and select Project Dependencies. Select the GameBase project as a project that the game project depends on. Now the GameBase project will always build before the game project
With that all finally set up (which took me about 4 hours), I was finally able to do some actual work. Actually I did a lot of copy/paste from the DirectX CreateDevice sample for creating the window and initializing the directX device. I now have a app that simply opens a window and draws it blue. As simple as it is, I can't tell you how happy I was to see it! There really is no better feeling than when you get something working that you have been frustratingly working on for way longer than you thought it should have taken.


My next goal of the project is to get a process manager created where all the game logic will be managed.

10/15/09

Where do I begin!

Howdy!

My name is Criss Martin and I'm a recently unemployed web developer trying to break into the game industry. It's not like I woke up this morning though and thought "I want to be a game developer." I've been working on and off for the last 6 years on independent game projects, but recently, like in the last 6 months or so, its mostly been on.

My goal for this blog is to chronicle my daily progress on any projects I'm working on as well as my overall progress of breaking into the games industry. Maybe someday, young developers will be able to use this blog as a helpful tool for breaking into the industry themselves (either as a how to or how not to, depending on how things go!).