Friday, September 21, 2007

Window System for XNA - New Release

Just to let everybody know that there should be a new release within the next week, basically when my internet connection is back up. The reason for the sudden release is because I've finally managed to fix the GUI rendering, with correct alpha values. The most important impact is that anti-aliased SpriteFont will be used from now on, and the old XNAExtras stuff is to be removed.

Project Site

If anyone is interested in what the problem was, and how I fixed it, then read on.

In the old system, every control was rendered to its own texture using render targets. Each child control would have its texture combined with those of the other children, to make up the texture of the parent control (after drawing itself). It was quite efficient because only the top level controls (generally windows) actually get their textures drawn to the screen, with the textures only redrawn when necessary, such as when the mouse hovers over a button, and a different image must be displayed. Render targets were also an easy way to perform clipping of child controls within their parent, and allowed the alpha value of a control to affect all children as well.

The problem with render targets was that control textures had to be drawn to a transparent texture, causing incorrect colour and alpha values to be produced during the alpha blending operation. In practical terms, it means that the edges of sprites with partial transparency and anti-aliased text would be mixed with white (or any other colour depending on the clear colour of the render target). This made either anti-aliased text unreadable, or made the edges of some controls the wrong colour. The reason I couldn't use SpriteFont, was because it created anti-aliased fonts. With XNAExtras I could make a simple font bitmap with colour keyed transparency, which made the text problem go away.

After playing with render states and pre multiplied alpha for a long time, I finally got fed up and tried to find another way to get it working. I was advised to draw directly to the screen, and use scissor rectangles to handle clipping. This worked great, except performance was abysmal. With just 4 complex windows on the screen, the framerate would start to drop. That was without any game running in the background! The reason for the poor performance was because scissor rectangles must be the same until SpriteBatch.End() is called. This means that I had a SpriteBatch.Begin() and End() call for every single control!

Next I decided to implement my own texture clipping, which all worked great, but there wasn't an obvious way to clip text. When using scissor rectangles for just text, the performance was still really bad. The final method was to use a hybrid approach. I would clip sprites on the CPU, and render text to textures which would be cached to allow fast draw calls. The text texture can then be clipped in the same way as the rest of the GUI sprites. Of course there was still the problem of partial alpha pixels being blended with the transparent texture colour. Basically I set the render states to draw with pre multiplied alpha, and set the background clear colour of the texture to the text colour, with the alpha channel set to 0. This means that the blending still takes place, but it produces the correct results. The performance is good once again!

So yeah, the project isn't dead, I've just had some big problems to deal with. Now that this is working, I will go back to adding more features like Xbox 360 support, and more widgets.

Monday, September 3, 2007

CodePlex Hosting and the Future

Hi guys. I've finally got full project hosting set up, but I decided to go with CodePlex in the end. It seemed well suited to my needs, and is already home to other XNA projects. I will not be using the current temporary forum anymore, but the discussions feature on CodePlex instead.

http://www.codeplex.com/wsx

I have updated the first new release by changing the name of the project, adding a license, and cleaning up the directory structure. The new name is Window System for XNA, instead of XNA Window System. It may seem like an unnecessary change, but it means that XNA is no longer in the official title, as Microsoft doesn't approve of that. I decided on the New BSD license, which is more permissive than the other open source licenses. Finally, the projects now reference binary DLLs, instead of requiring all projects to be included in the solution.

I have been working on fixing the current bugs, and have decided to make some rather large changes along the way. The GUI will no longer be drawn with render targets, because I couldn't get premultiplied alpha values to work correctly, which screwed up font rendering. The font support provided in XNA Refresh will now be used instead of XNAExtras. I will also be adding joypad support for the Xbox 360 controller as well as regular Windows controllers. Support for the Xbox 360 will be added in the longer term (when I find somebody with an Xbox 360 to implement it). These and many other changes will be added over the coming months. You can keep up to date with the project by using the source control feature of the CodePlex project.

Please consider helping with the project, either by contributing code, working on documentation, artwork, or by submiting bugs and helping out in discussions.

Tuesday, July 17, 2007

Project Hosting

It's been quite a while since my last post. I haven't received much feedback about the XNA WindowSystem lately, so either people aren't having problems with the library, or they assume the project is dead.

I assure you that the project is not dead, I've just been working on some other stuff while I decide what to do next with the GUI. For starters, the project now has a home. It will be hosted by the guys at http://www.legendro.net/, who I believe are using the library in their upcoming game. At the moment, a forum and a bug tracker have been set up. It would be cool for some of you to sign up to the forums to ask questions, make feature requests, and generally support the project. I am hoping to get the version control software and a wiki for documentation set up soon. The aim of all this is to recruit some developers to help keep the project going. I don't want it to get to the stage where a ton of competing libraries are released, effectively killing off my GUI.

Check out the new home at http://xnaws.legendro.net/

Many thanks to Anthony for the free hosting, and all the effort in setting it all up.

Oh yeah, and I'm starting a new job in the games industry soon. Wish me luck!

Monday, April 30, 2007

Tutorial 2

I haven't had much feedback regarding the first tutorial, so I'm assuming nobody has had any problems with it. I hope it was useful to some of you.

This next tutorial will cover how to create a class that inherits from Dialog, and retrieve some useful information from it. This method of using windows was developed while putting together my tile map editor application. It is the best way of using the GUI that I have discovered so far, and is pretty closely based on other window systems I've used in the past. I'm sure some other methods will expose themselves in the future.

Setting Up The Project

I have already covered setting up a new project, and setting up the GUIManager in the previous tutorial, so you can go back and look it up there if necessary. Simply follow Tutorial 1 up until the Adding Controls heading, and you'll be ready to go.

Creating The Dialog

We will create a Dialog box, where the user can enter their name into a textbox. It will have OK and Cancel buttons, so that the dialog can return a result.

The first thing to do is to create a new class called UserDetailsDialog, which is inherited from Dialog. Dialog is inherited from Window, and the only addition is that it returns a result, which can be queried after the Dialog is closed.


using System;
using Microsoft.Xna.Framework;
using XNAWindowSystem;

namespace GUI_Testbed
{
public class UserDetailsDialog : Dialog
{
}
}


Next we can add a few fields to our new class.


private const int LargeSeparation = 10;
private const int SmallSeparation = 5;
private TextButton OKButton;
private TextButton cancelButton;
private TextBox nameTextBox;


The LargeSeparation and SmallSeparation constants are something I add to all my dialogs. They allow me to control the spacing between the window edge and between dialog controls. I use LargeSeparation for the window edge, and between unrelated controls. SmallSeparation is used for the space between related controls, like between a textbox and it's label.

The rest of the fields are controls that we will need to keep track of after they are set up. We will need to get the text from nameTextBox for example. Other controls like labels can just be added without keeping a reference if they don't need to change, or we don't need to query them after events are triggered.

Next we should add a property, so that the user's name can be queried from outside the class.


public string Name
{
get { return nameTextBox.Text; }
}


The constructor sets the control properties and adds them as child controls, as well as settings it's own properties.


public UserDetailsDialog(Game game, GUIManager guiManager)
: base(game, guiManager)
{
// Name label
Label nameLabel = new Label(game, guiManager);
Add(nameLabel);
nameLabel.Text = "Name:";
nameLabel.X = LargeSeperation;
nameLabel.Y = LargeSeperation;
nameLabel.Width = 75;
nameLabel.Height = nameLabel.TextHeight;

// Name textbox
this.nameTextBox = new TextBox(game, guiManager);
Add(this.nameTextBox);
this.nameTextBox.Initialize();
this.nameTextBox.X = nameLabel.X;
this.nameTextBox.Y = nameLabel.Y
+ nameLabel.Height
+ SmallSeperation;

// Set the window width to the default textbox width
ClientWidth = nameTextBox.Width +
(2 * LargeSeperation);

// Cancel button
this.cancelButton = new TextButton(game, guiManager);
Add(this.cancelButton);
this.cancelButton.Text = "Cancel";
this.cancelButton.X = ClientWidth
- this.cancelButton.Width
- LargeSeperation;
this.cancelButton.Y = this.nameTextBox.Y
+ this.nameTextBox.Height
+ LargeSeperation;
this.cancelButton.Click
+= new ClickHandler(OnButtonClicked);

// OK button
this.OKButton = new TextButton(game, guiManager);
Add(this.OKButton);
this.OKButton.Text = "OK";
this.OKButton.X = this.cancelButton.X
- SmallSeperation
- this.OKButton.Width;
this.OKButton.Y = this.cancelButton.Y;
this.OKButton.Click
+= new ClickHandler(OnButtonClicked);

// Set the window height to the amount needed to show
// all controls.
ClientHeight = this.OKButton.Y
+ this.OKButton.Height
+ LargeSeperation;

// Set the window title
TitleText = "User Details";

// This dialog does not need to be resized by the user
Resizable = false;

CenterWindow();
}


Note that I add child controls before setting their properties. This is because some controls don't become fully set up until they are initialised, which happens automatically when they are added to the GUI or another control. You could also just call Initialize() manually, but who needs that kind of extra typing?

Also notice that control positions are set in relation to each other. I find this keeps the layout quite dynamic, especially for resizeable windows. I will consider providing layout managers in a future release, perhaps similar to those found in the Java Swing library.

The TextBox and TextButton controls don't have their Width or Height properties set. That's because some controls have useful default sizes, which allows some flexibility when modifying the default GUI settings.

Next we will add an event handler to the class, which will be called whenever a button is clicked. The buttons had this event handler added for their Click events in the constructor.


protected void OnButtonClicked(UIComponent sender)
{
if (sender == this.OKButton)
SetDialogResult(DialogResult.OK);

CloseWindow();
}


This method simply checks which button was clicked, and sets the result accordingly before closing the dialog. We don't bother checking for the Cancel button because cancel is the default result. This is because that is also the result when the user clicks on the window close button. If necessary the close button can be removed by setting the HasCloseButton property to false.

Using The Dialog

Back to the main game class which I have called Tutorial2, and we're going to attempt to use our new dialog.

The application will show an information message box, explaining how to use our simple program, then show our User Details dialog box when the user presses enter. If the user clicks on the OK button, a message box will display the name entered into the dialog textbox.

Firstly, add a dialog reference to our Game class.


private UserDetailsDialog dialog;


Next add an event handler that will be called when the user presses a key. In the constructor add the following code.


// Add a key down event handler
this.input.KeyDown += new KeyDownHandler(OnKeyDown);


Then create the event handler method.


private void OnKeyDown(KeyEventArgs args)
{
if (args.Key == Keys.Enter)
{
// Only create a new dialog if one isn't already
// shown.
if (this.gui.GetModal() == null)
{
// Create and show dialog
this.dialog =
new UserDetailsDialog(this, this.gui);
this.dialog.Close +=
new CloseHandler(OnDialogClosed);
this.dialog.Show(true);
}
}
}


Basically this function just checks that no other modal window is already opened, if not then it pops up a new User Details dialog. Modal just means any window that has exclusive focus, such as a message box, or our dialog. To show a window as modal, pass true to the Window.Show() method, otherwise pass false.

When your program calls a modal dialog in Windows, it takes full control of you're processing until the dialog is closed. Unfortunately, our system is a little different. We have to add an event handler to the window's Close event, that checks which window was closed, and acts accordingly.

The following code is the method called when our dialog is closed.


private void OnDialogClosed(UIComponent sender)
{
if (sender == this.dialog)
{
if (this.dialog.DialogResult == DialogResult.OK)
{
MessageBox message = new MessageBox(
this,
this.gui,
"Name: " + this.dialog.Name,
"User Name",
MessageBoxButtons.OK,
MessageBoxType.Info
);
message.Show(true);
}

// Remove event handler so garbage collector will
// pick it up.
this.dialog.Close -= OnDialogClosed;
this.dialog = null;
}
}


A message box is shown repeating the name entered by the user, only if the result was OK. Then the event handler is removed from the dialog and the dialog is set to null, to prevent it from lingering about in memory. This is very important to remember, especially in a real application. I've caught out by event handlers and the garbage collector on few occasions.

The final things to add is a message box explaining how to use the application. This should be placed in the Game class Initialize() method, to ensure it's shown at the start of the program.


// Show a message box informing the user how to use the
// program.
MessageBox info = new MessageBox(
this,
this.gui,
"Press enter to bring up the dialog.",
"Info",
MessageBoxButtons.OK,
MessageBoxType.Info
);
info.Show(true);


Conclusion

I hope this tutorial was helpful, it was definitely more difficult to write than the last one. I would really appreciate any feedback, because I'm quite new to writing documents like this.

I'm sure some of you are wondering where to find the source code for my tutorials, well they're not available at the moment. I will add it to the GUI_Testbed project for the next release of the WindowSystem.

I'm not sure what to cover in the next one. I'll probably wait until I get some responses from this one before I decide. I think I should cover skinning and modifying the GUI at some point. Any ideas?

Thursday, April 26, 2007

Fixed Project Files

Now that I have an Internet connection again, I decided to fix the project files that you guys have had problems with. It seems Visual Studio uses relative paths for everything, except the XNA content assemblies.

Download Source Code

This release is exactly the same as the last one, so don't bother downloading if you've already fixed your project files.

Microsoft have recently released an update for XNA, which I will be checking out tonight. It has font support, although I gather it's fairly basic. I will try to integrate this into the GUI, although I suspect I will run into the same problems I had before with their font sample code. In case you haven't read my comments from a while ago, the problem is that anti-aliased fonts simply won't work with the GUI at the moment. The only way I can see it working is to implement multiple passes when rendering the controls. Personally I think that small font sizes should be used anyway, which look better without anti-aliasing.

Monday, April 23, 2007

Quick Update

I've been pleased to learn that some people have started to use my window system, at least to play around with. If anybody manages to finish a game or tool that uses the GUI, then I'd love to hear about it.

Obviously the system is in it's early stages, and is yet to be used in an actual game. The good news is that I now have an Internet connection on my development computer now, so I'll be able to resume work on it sometime over the next few days. Before I do that however, I'd like to write another couple tutorials to bring everybody up to speed on how to use the system. Also, I'd like to write an article on the design of the system, which may help people to understand it better, especially for those who wish to expand upon it.

I'm hoping to finish the first version of my XNA tile map editor I've been working on in parallel with the window system. The source code for that should shed some light on how best to use the system. The tutorials are actually based on what I learned from building that application.

Regarding the Internet connection, I spent several hours yesterday looking for that perfect spot in my basement room where I could get a signal from the wireless router with more than a one bar signal strength. Turns out it's in the closet, so the computer is currently half inside my room and the closet!

Wednesday, April 18, 2007

Tutorial 1

This first tutorial will cover setting up the GUIManager, adding new controls, and handling their events.

Setting Up The Project

The simplest way to begin is to use the GUI_Testbed project as a starting template. I simply created a new source file containing a class called Tutorial1, and set that as the startup Game object in Program.cs. You could also just use the existing GUI_Testbed.cs if you don't feel like starting from scratch.

Setting Up The GUIManager

The first thing to do is to add a couple using statements for the InputEventSystem and the XNAWindowSystem.


using System;
using Microsoft.Xna.Framework;
...
using InputEventSystem;
using XNAWindowSystem;


Now add some fields.


private GraphicsDeviceManager graphics;
private InputEvents input;
private GUIManager gui;


In the constructor we set up these objects, and add input and gui to the list of game components. It is important that the InputEvents object is created before the GUIManager object because it adds itself to the game services in the constructor, which the GUI will need access to. Not creating an InputEvents object at all will cause the program to crash.


public Tutorial1()
{
this.graphics = new GraphicsDeviceManager(this);

this.input = new InputEvents(this);
Components.Add(this.input);

this.gui = new GUIManager(this);
Components.Add(this.gui);

// GUI requires variable timing to function correctly
IsFixedTimeStep = false;
Window.Title = "XNA Window System Tutorial 1";
}


The GUIManager object should be initialised in the overriden Initialize() method, before any child controls are added. This is so that order of resource loading can be predicted.


protected override void Initialize()
{
// Has to be initialised before child controls can be added
this.gui.Initialize();

base.Initialize();
}


You will also want to override the Draw() method, to clear the screen each frame, although this probably doesn't affect the GUI as it handles drawing itself.

Adding Controls

I'm going to use a menu bar with various menus and menu items as an example. This will show how to create controls, how to add them to the GUI, and how to handle their events.

First we should add some fields, which are the menu bar and the menu items that the user will actually select. This means that we don't actually need to keep a reference to the 'File' menu for example, because it handles itself. We do need to keep references to child menu items that will actually be clicked, so that we can determine which one was selected. An example would be the 'New' or 'Save' menu items.


private MenuBar menuBar;
private MenuItem newMenuItem;
private MenuItem openMenuItem;
private MenuItem saveMenuItem;
private MenuItem saveAsMenuItem;
private MenuItem exitMenuItem;
private MenuItem undoMenuItem;
private MenuItem redoMenuItem;


Next we have to actually set up the GUI objects, and add them to the GUI. This should take place in Initialize(), after the GUIManager has been initialised.


this.menuBar = new MenuBar(this, gui);
MenuItem fileMenu = new MenuItem(this, gui);
fileMenu.Text = "File";
this.newMenuItem = new MenuItem(this, gui);
this.newMenuItem.Text = "New...";
fileMenu.Add(this.newMenuItem);
this.openMenuItem = new MenuItem(this, gui);
this.openMenuItem.Text = "Open...";
fileMenu.Add(this.openMenuItem);
this.saveMenuItem = new MenuItem(this, gui);
this.saveMenuItem.Text = "Save";
this.saveMenuItem.IsEnabled = false;
fileMenu.Add(this.saveMenuItem);
this.saveAsMenuItem = new MenuItem(this, gui);
this.saveAsMenuItem.Text = "Save As...";
this.saveAsMenuItem.IsEnabled = false;
fileMenu.Add(this.saveAsMenuItem);
this.exitMenuItem = new MenuItem(this, gui);
this.exitMenuItem.Text = "Exit";
fileMenu.Add(this.exitMenuItem);
menuBar.Add(fileMenu);
MenuItem editMenu = new MenuItem(this, gui);
editMenu.Text = "Edit";
this.undoMenuItem = new MenuItem(this, gui);
this.undoMenuItem.Text = "Undo";
this.undoMenuItem.IsEnabled = false;
editMenu.Add(this.undoMenuItem);
this.redoMenuItem = new MenuItem(this, gui);
this.redoMenuItem.Text = "Redo";
this.redoMenuItem.IsEnabled = false;
editMenu.Add(this.redoMenuItem);
this.menuBar.Add(editMenu);

// Add menubar to gui
this.gui.Add(this.menuBar);


You may notice that some of the menu items have a property called IsEnabled set to false. This basically makes the item grey and unclickable, just how windows does it. This property only applies to MenuItem objects currently, but at some point in the future, I will probably make it apply to all controls.

Now if you run the application, it should show a menu bar with all the new menus and menu items.

Control Events

Next we will add event handlers that will be called whenever a menu item is clicked. The reason for holding references to menu items is for comparison with the clicked control, determining which one was actually clicked.

So add the following code to the Initialize() method, probably after the menu bar is added to the GUI.


// Add event handlers
this.newMenuItem.Click += new ClickHandler(OnMenuItemClicked);
this.openMenuItem.Click += new ClickHandler(OnMenuItemClicked);
this.exitMenuItem.Click += new ClickHandler(OnMenuItemClicked);
this.undoMenuItem.Click += new ClickHandler(OnMenuItemClicked);
this.redoMenuItem.Click += new ClickHandler(OnMenuItemClicked);


Finally we need to add a new method that is called whenever a menu item is clicked. We simply check which item was clicked, and act accordingly.


private void OnMenuItemClicked(UIComponent sender)
{
if (sender == this.newMenuItem)
{
MessageBox messageBox = new MessageBox(
this,
gui,
"New clicked!",
"Tutorial 1",
MessageBoxButtons.OK,
MessageBoxType.Info
);
messageBox.Show(true);
}
else if (sender == this.openMenuItem)
{
MessageBox messageBox = new MessageBox(
this,
gui,
"Open clicked!",
"Tutorial 1",
MessageBoxButtons.OK,
MessageBoxType.Info
);
messageBox.Show(true);
}
else if (sender == this.undoMenuItem)
{
MessageBox messageBox = new MessageBox(
this,
gui,
"Undo clicked!",
"Tutorial 1",
MessageBoxButtons.OK,
MessageBoxType.Info
);
messageBox.Show(true);
}
else if (sender == this.redoMenuItem)
{
MessageBox messageBox = new MessageBox(
this,
gui,
"Redo clicked!",
"Tutorial 1",
MessageBoxButtons.OK,
MessageBoxType.Info
);
messageBox.Show(true);
}
else if (sender == this.exitMenuItem)
Exit();
}


This first tutorial was really simple, but should show you the basics of using the window system. It should be enough if all you want to do is add a couple buttons to your game. In the next tutorial I will show how to create a class that inherits from Window, to show how to begin to create a real application.

Saturday, March 31, 2007

XNA WindowSystem Source Code

Tomorrow I'm moving back to England, and won't be able to work on the project for a little while, so I thought this was as good a time as any to release an early version of my GUI for XNA. For screenshots, see my previous post.

Download Source Code

Features
  • Input events
  • Individual control transparency
  • Controls can have multiple skins, representing different states (hover, pressed etc.)
  • Skinnable at the GUI level through static calls, or at the control level
  • GUI and input event system implemented as game components
  • Custom mouse cursors
  • Modal windows
High-Level Controls
  • Check boxes
  • Combo boxes
  • Dialogs
  • Display settings dialog
  • Icons
  • Images
  • Image buttons
  • Text buttons
  • Labels
  • Menus
  • Context menus
  • Message boxes
  • Radio buttons
  • Radio groups
  • Vertical scrollbars
  • Text boxes
  • Windows
Future Plans
  • Flexible system for control animations
  • Possibly a settings file for customizing skins
  • Possibly bring the GUI into 3D for cooler animations
  • Context menus for any control, currently has to be done manually for each case
  • More complete textbox, with text selection and copy/paste
  • Horizontal scrollbars
Most of those features wouldn't be that hard to implement, it's just a matter of time.

The code is in a pretty stable state at the moment, but I'm sure there's hundreds of bugs to be found in there. Please feel free to contact me regarding any bugs, questions, or suggestions.

One know issue is that hideous amounts of temporary textures are created while resizing windows. I know the reason, but am waiting to find a graceful solution. Basically the GUI draws each control to it's own texture, allowing simple clipping and transparencies. While resizing windows, the control texture is recreated many times a second, sometimes using up all available texture memory. The simple fix in place at the moment, is that the garbage collector is called whenever this happens. Not pretty, but it doesn't crash. Everything goes back to normal when resizing ends.

This project uses code based on the Event Based Input System of the XNA5D library, and to a lesser extent the GUI components. The XNA5D library is by John Sedlak, and is available at jsedlak.org/Xna5D.

The library also uses the BitmapFont portion of XNAExtras for text rendering. To add new fonts to your projects, use the BMFontGen tool which part of the same project. XNAExtras is by Gary Kacmarcik, and is available at blogs.msdn.com/garykac/articles/749188.aspx.

Finally, although I drew the complete graphical skin, the message box icons are by Ken Saunders, and are available at mouserunner.com/Spheres_ColoCons1_Free_Icons.html.

Sometime soon I will post an overview of the system, and possibly a few quick tutorials on how to use it. It's pretty well documented, so this shouldn't pose too much of a problem for most of you.

In addition, I'll be releasing the source code of my first project to actually use the GUI, a tile map editor. It's already in a pretty usable state, but is very much a work in progress.

Oh yeah, and I need a name for the project. At the moment I'm just using WindowSystem for XNA, which is really just a description. Any ideas would be appreciated.

Thursday, March 29, 2007

XNA WindowSystem Screenshots

It's been a while since my last post, but I've been working hard on my GUI for the XNA Framework. There's a couple already available for free on the web, but I was really going for more of a complete window system, that could be used for game tools as well as game interfaces.


These screenshots show most of the controls available, and examples of them in use. As part of the development process, I've been working on a tile map editor to test out how the GUI should be used, and to uncover bugs.


Friday, March 2, 2007

XNA Framework

I started using the XNA Framework about a month ago, and thought I would share some of my opinions with you.

The first game I wrote was a version of Pong in Pascal at college, just as I was learning to program. I thought that if I really wanted to program games, I should start near the beginning. Shortly after I got a working version of Tetris up and running, which felt incredible at the time. In the second year we moved onto C++, and my one true love, object oriented programming! I spent that final year learning as much as possible, finally handing in a tile map demo as my final project. At university I was using DirectX to write 2D and 3D games, as well as simple online games in Java.

Now back to the XNA Framework. Considering my background in C++ and DirectX, I was reluctant to even give it a try. I'm sure lots of people feel the same, that they would lose control over their high performance game engine, and that C# could never compare to the speed offered by C++. I have to admit, I was very wrong.

The average hobbyist isn't going to be creating incredibly complex games, that would make the speed difference a serious issue. It's even been speculated that XNA games can be comparable in performance to a C++/DirectX equivalent. Regardless of whether that's true or not, the fact remains that this is a great platform for people who want to learn to make games, without having to handle all the technical details from day one.

From my perspective, I was sick of having to deal with every low-level technical detail required by game engines. Game studios have large teams working to achieve similar things. Can one person working part-time on a project reproduce that much work? Sometimes, but not often.

XNA allows programmers to concentrate more on the actual game, rather than developing the complex libraries used to traditionally program games. The integrated content pipeline is sheer genius, making game assets just as much a part of the project as the source files. I haven't dealt much with this side of the framework yet, but loading textures is a breeze!

I would recommend anybody thinking of learning game programming to give C# and the XNA Framework a try. It can take a lot of the complicated stuff out of the picture, but provide more advanced features if they are required, mainly though shaders.

I have a warning for people who might think that XNA makes programming games easy, like a click and play game creator. It doesn't. You still have to learn most of the same theory, and have a fair amount of experience with object oriented programming. Having said that, C# is a good place to start learning good object oriented design. For some reason C++ lures people into writing bad C-style code.

I think I'm rambling now, but I'd just like to say that people with games programming experience should also give it a try. If it can make you more productive by removing unnecessary details, think of what you could produce in the amount of time a C++ project might take. As a learning project I've been working on an XNA GUI for several weeks. I'm really pleased with the results, but can't wait to start making some games!

Wednesday, February 28, 2007

C# Documentation

Coming from a C++ background, documentation in my source code was limited to sparse comments. At university we concentrated on Java programming, which has built-in support for javadoc tags. At first I didn't know anything about javadocs, or have any desire to use such a tool, but a tutor insisted that assignments come with full HTML documentation. The obvious conclusion to this is that I realised how valuable documentation could be, especially when it is written directly in the source code. This makes keeping documentation up to date more convenient, because it can be updated as the code changes.

Now when using Java or C++ I always document code, although I have never been as happy with the tools for C++ document generation as with javadoc. I think the main reason is that javadoc is so easy to use, and is often integrated with Java IDEs. Another reason is that I like the look and structure of the javadoc output, I always meant to put some work into customizing the output of my C++ documentation, but never got round to it.

I recently started using C#, and I thought having XML documentation as part of the language was a fantastic idea. The only problem is that there aren't any good tools available yet for generating HTML output. I spend hours trying out what was currently available (for free) last night.

The first program I tried was NDoc, which has been widely used in the past. Unfortunately it hasn't been actively developed for a while, and doesn't support .NET 2.0. I did find an alpha version with support, but I kept getting exceptions, and I wasn't impressed with the output.

I tried a couple other programs without much sucess, until I found a command-line tool by Microsoft called Sandcastle. From what I understand it is still in development for the next version of Visual Studio. That's why it currently takes a list of complicated commands to get anything to work. I downloaded a GUI tool for Sandcastle, but it just wouldn't work for me.

I guess what I really wanted was a tool for C# that was as easy to use as javadoc. For now I might just write a simple GUI for automating Sandcastle document generation. I would also like to customize the transformations, to provide a nicer output. I always hated the MSDN style documentation, it seems like a great way to hide information.

Tuesday, February 27, 2007

New To Blogging

This is my very first blog post, so I guess there won't be much content to this one.

At the moment I'm working with the XNA Framework to produce reusable components to be used in future game projects. I started about 3 weeks ago, by working on a flexible GUI for use in games and their editors. I think I'll now be focusing on tools for a while, such as a sprite and map editor.

At some point I'd like to share what I've learned about the framework so far, as well as providing the source code and information of current projects. I'd also like to write some general ramblings, the kind we all think about every day.