Using a Database for Logging Events

One of the things I've been trying to do with my new engine/game is improve on The vast majority of games use a system for capturing errors/information like the one found here. While it might not be XML based, the fact of the matter is that it usually goes to a file on the users computer. In order for the developer to get the information the user must find the file, upload it, etc. This usually never happens, even in beta testing.

There are ways to automate this a bit by having an application that automatically uploads the file to us but we still have an issue. Specifically what if the program crashes, they start it back up (thus overwriting the error log), and then send us the error log sans error. To fight this we need either to continue to append to the file, thus creating potentially a huge file that would take forever to parse not to mention upload, or we create a new file each time the program is run (good luck finding the one with the error).

So how can we deal with these issues in a manner that wont cause people to want to beat us with sticks? Well one that I've been toying with is using a database. A database can hold numerous entries, is easily searchable, and can be centralized on a server instead of on the individual user's machine. So lets take a look at how we might do this.

Setup The Database

I'm not talking about installing the database or get into a discussion of whether you should use MySQL, SQL Server, etc. So at this point I'm just going to assume that you've made your decision, installed it, and configured it correctly on your server. However we still need to setup the tables. For this example we're only going to use a simple example using MySQL and C#. Assume that we setup a database/table using the following SQL:

create database ErrorLog;

use ErrorLog;

create table Errors (ErrorID int auto_increment not null, message char(5000), ErrorType int, File char(1024), Line int, primary key(ErrorID));

As you can see, we should have at this point a simple table that has an ID number, a spot for a message, error type, the file that the error came from, and the line number.

Setup The Code 

Now in order to insert the information we can use a function like this:

public static void Error(string message,int ErrorType,string File,int Line)
{


System.Data.Odbc.OdbcConnection Connection;
string ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};" +
               "SERVER=ServerName;" +       //The server location should go here
               "DATABASE=ErrorLog;" +         //The database name, in this case ErrorLog
               "UID=UserID;" +                     //Whatever you've setup as the user name for the database
               "PASSWORD=Password;" +      //Whatever you've setup as the password for the database
               "OPTION=3";

Connection = new System.Data.Odbc.OdbcConnection(ConnectionString);
Connection.Open();
System.Data.Odbc.OdbcCommand Command;
string CommandString = "insert into Errors(message,ErrorType,File,Line) values (" + message + "," + ErrorType + "," + File + "," + Line + ");";
Command = new System.Data.Odbc.OdbcCommand(CommandString, Connection);
int LinesInserted = Command.ExecuteNonQuery();

Connection.Close();


}

And voilà, we have a central database that contains all errors that occur, tells us where in the code they occur, etc. with the user not having to lift a finger.

Now there are some downsides to logging your events this way. First and foremost is that it is potentially rather slow. You have to wait for a message to be sent from the user to the database and back. So sending a couple of messages each loop will likely make your application crawl. Instead we could save the information onto the users machine in an XML file and only send the data when the application is closing. Or potentially we could only use this method during development and testing of the application and remove it for a more traditional system when it hits production.

Another issue is the fact that the person has to be connected to the Internet in order for this to work. However for games that are either strictly multiplayer (World of Warcraft, Shadowrun, etc.) or use a system like Steam might not be hindered by this aspect.

Lastly we have to worry about privacy issues. Any time we send information from the user's machine, we have to tell them and let them have the ability to opt out if they wish. If we do not, we risk angering quite a few people. So basically make sure they know about it, can opt out, make it anonymous, etc. and you shouldn't have many issues here.

So while this might not be the perfect solution for every game, it definitely is something to consider for some. The key is to experiment and find what works for you and your situation.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 2/17/2008 at 1:08 PM
Tags: , , , ,
Categories: Game Programming | Database | C# | MySQL
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

ASP.Net AJAX Toolkit Fix

I know this isn't game related but this is one item that has come up multiple times for me (and has annoyed me to no end). For those developing websites in ASP.Net and are using the Control Toolkit might run into a problem with IE 6. Specifically any popup item is overlapped by dropdown menus and a couple of other items. The reason for this is that these items are rendered in their own window. This is usually fixable by rendering an IFrame between the popup item and the dropdown.

You may be asking yourself, why haven't they done this yet? They have, but their code has one flaw. If you look in the PopupExtender class there is a function called addBackgroundIFrame. This function is suppose to put an IFrame behind the control and overlap the selects. In certain situations this works but in many it doesn't. The reason for this is rather interesting. Find the following line:

childFrame.src="javascript:'';";

And change it to the following line:

childFrame.src="javascript:'<html style=\"background-color:black\"></html>';";

and comment out the following line:

childFrame.style.filter="progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)";

Recompile the application and you'll see what the problem is with the code. Specifically the IFrame is being rendered in completely the wrong position. And amazingly enough there is a fix for this (although make sure to change the code that we editted above back to its original state first). Below the call to setBounds, simply put the following code:

childFrame.style.top=element.style.top;

childFrame.style.left=element.style.left;

and suddenly it works. Since this annoyed me to no ends and it seems as though the group in charge of that project isn't going to change it any time soon, I figured I'd help out everyone else that found this annoying.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 2/16/2008 at 11:41 PM
Tags: , , , ,
Categories: Web Design
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Using Your Web Page Effectively

There are many, many groups that are formed on the likes of GameDev.net that never get off the ground. This is usually due to a couple of reasons:

  • Lack of planning
  • Lack of communication
  • Lack of motivation

All three of these things need to be addressed prior to beginning a new project.  And while there are plenty of articles about the planning and motivation aspects, I find that the communication aspect usually is ignored. Usually what occurs when a group starts up is they create some sort of version control (SVN, etc.), setup a website (for showing off their work), and communicate with one another using email or IM (or Facebook or something along those lines). While communicating using these items is a good start but they can do better. Specifically we can use that website to store information, communicate with one another, and even automate tasks for us.  So let's go over some examples of things we can do.

Setup a Wiki

This is probably the easiest thing we can do to improve our site. Setting up an internal wiki, or really any permanent place to post information, allows us to post things in a permanent location about our product. This is especially useful as most projects have a lot of turnover.

For instance we may have a scripting language that we created specifically for the game (while unlikely, let us assume this anyway). At the same time we may only have one person that truly understands the scripting language. If this person leaves, we're stuck trying to figure it out. However if we place a rather comprehensive description of the language on our wiki, we wont have as much downtime.

Use a Blog

With a lot of groups being rather small in size, this might not be the best option. However in situations where you have multiple groups with many people involved, it can be a good way to communicate. For example the scripting language that was mentioned earlier may have been created by a developer group but may actually be used by a designer. In order to let the designer know about changes, added functionality, etc. we can use a blog.  This has the added benefit over email as the blog is a permanent item that anyone can go back to and read.

Store Bug Reports

While the last two items were designed to facilitate communication, this is something that is a move toward automation.  Almost every game in existence has a file that it outputs any errors, information about the computer running the program, various metrics, etc. Usually the output is XML, HTML, a plain text file, etc. While this can be useful for a sole developer, its a pain to email or upload those files to one another. What we can do instead is have a central database on our website that holds this information for us.

A central database can keep track of each run of the application, hold various metrics, any errors that occur, etc. At the same time we can create pages that can output this information in an easily readable format and allow us to search through the information easily.

Conclusion

These are just a few examples of things that we can improve communication within our group by using our site. There are quite a few other things that we can do though and not every option will be appropriate for every group. The best thing to do is to experiment and find what is best for the situation.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 2/16/2008 at 2:28 PM
Tags: ,
Categories: Game Programming | Web Design
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed