Finish the...
28 November 08 02:48 PM | mitchw | 1 Comments   

When we shipped XNA Game Studio 3.0 last month, and then turned on Xbox LIVE Community Games this month, that, to me, really completed our initial vision for XNA Game Studio, the changes in the way games are made, and creating opportunities for a new class of game developers.  While there will always be a list of things to be added or improved to XNA Game Studio and the XNA Framework, I was having trouble finding tough, interesting problems to solve, which is what motivates me.

So I’ve taken my love of games, of creating platforms and tools, and of a particular game series and found my next big challenge to tackle.  A couple of weeks ago, I started as a Program Manager on the Microsoft Halo Studio team.  I’m joining a(nother) team filled with very talented people and I’m excited about the possibilities.

Unfortunately, what I’ll be working on won’t lend itself to public blogging much anymore…not that I’ve been a regular blogger anyway.  And I usually don’t post (or twitter) about day to day stuff.  Me getting another Diet Dew from the fridge just doesn’t seem that interesting. J  I’ll keep this blog around for a bit and see how it goes.

I’ll still be involved in the XNA Game Studio community, but now from the “other” side…a creator…as I continue to learn, create, and wait to see what the team comes up with next.

-Mitch

The One About Storage
15 October 08 08:31 PM | mitchw | 4 Comments   

So I’ve played quite a few XNAGS games, and quite a few that have been released to Xbox LIVE Marketplace as part of the Xbox LIVE Community Games beta.  Based on the types of issues we’ve seen and feedback in general about good development practices, we set out to create the “best practices” for creating Community Games document.  This will be a living document that is continuously updated and expanded upon as we find out what works, what doesn’t work, what is difficult, and what are some things most games should attempt to do.  There is one issue, however, that I’ve seen crop up quite often and I figure it’s worth discussing in more depth what it is, what causes it, and how to prevent it.

 

Let’s call it the “Storage API Hang of Fun”.  You’ve probably run across it.  You build your game, add save game or high score support and being a good XNAGS citizen, use the Storage APIs to get a hold of a proper StorageContainer so you can read and write the files to the correct place.  Everything seems to be working well; it’s time to beta test!  So you package up your game and hand it out to a few people to try.

 

“Your game freezes my Xbox 360”

 

What? How can this be? It was working perfectly on my machine! I thought the purpose of a console was that it is a fixed hardware platform that is easy to develop against since everyone will have the same hardware!

 

Except there is one area that each console can be slightly different: Storage devices, or more specifically, the number of devices available.  Ask the person who is having trouble if they have a HDD and a Memory Unit plugged in.  Most likely they do.  Have them remove the Memory Unit and I bet the game starts to function properly.  Problem solved!  But why did it happen? Let’s take a look into a couple of areas that have led you down this path.

 

The Guide

In XNA Game Studio 2.0 we provided access to Gamer Profiles and the Guide functionality of the Xbox 360.  The Guide is a system service that is running in the background of your game.  This is the UI that is displayed when the user hits the silver Xbox 360 button on their controllers, want to create a Friend request, view their messages, etc.  The system “hooks” our call to GraphicsDevice.Present (which gets called for you inside of Game.EndDraw).  Inside of this, it performs any input processing and drawing, which is how it can draw on top of your game without you needing to do anything.

 

The only thing you need to do is to make sure your game is running, i.e. having Update and Draw called into (and you allowing them to return) at least 15 times a second (the recommended minimum).  As long as your game isn’t blocked on the main thread, the Guide will be able to come and go as it pleases and everyone is happy.

 

Unless you block the main thread.  This is why we designed many of the Guide APIs to use the .NET asynchronous call pattern.  If the particular Guide API you are calling requires user input and expects data to return, then you have to call the Guide API such that it occurs on a background thread…this allows your main thread to continue to run, which will eventually call GraphicsDevice.Present.

 

Storage APIs

Guide.BeginShowStorageDeviceSelector is one such API.  The purpose of this API is to allow the user to choose what storage device they would like the game to read and write from.  Since the Xbox 360 can have any combination of a HDD and up to two Memory Units, a “well behaved” game will allow the user to choose whichever device that is present.

 

When we released XNA Game Studio Express, we provided a non-asynchronous Guide.ShowStorageDeviceSelector API, knowing that on the Xbox 360, calling this on the main thread would instantly lock your console.  We provided for those that would like to call this blocking version from a background thread.  In XNAGS 2.0 we introduced many more Guide APIs and we wanted to clean things up a bit and make them more consistent.  We realized that the correct way to call this API was to call it asynchronously, so we removed the blocking version and helped those unfamiliar with the pattern to move their code.  The native APIs that we call by default won’t display the selection UI if there is only one storage device available.  Instead it will return instantly with the “default” device.  In our first release, we passed in a flag that basically says “always show the UI”.  In another effort to help make this easier, we stopped passing this flag in XNAGS 2.0 so that if only one device is available, the call will return immediately.  Unfortunately the combination of these two changes (requiring you to call it asynchronously and not display the UI if there is only one device), led many people to write the following code:

 

 

IAsyncResult result = Guide.BeginShowStorageDeviceSelector(...);

 

while(result.IsCompleted == false)

{

}

 

StorageDevice device = Guide.EndShowStorageDeviceSelector(result);

 

 

 

If you call this piece of code on the main thread…what will happen?  The Begin call will succeed, we’ll then sit there and spin until the user has selected the device they want to use and the operation is “complete”.  We’ll then call the End method and get the device.  But if we’re spinning on IsCompleted, then that means GraphicsDevice.Present is not getting called, which means the user won’t be able to select a device, so that while condition will never complete.

 

The game is now deadlocked.  The user will have to reboot their Xbox 360.

 

Unless…they only have one storage device available.  In which case, IsCompleted will immediately be true, you’ll get down to the End call and everything will return normally!

 

So, a long description of a relatively simple problem and one that is easy to get yourself into.  How do we fix it?  By handling the async pattern correctly.  You have two choices and they are both valid.  One is to store the IAsyncResult as a member variable in your game and check IsCompleted inside of your Update call.  The other is to pass in a callback method to BeginShowStorageDeviceSelector.  Once the operation is completed, your method will get called, the IAsyncResult will get passed to you, and you can use it to complete the operation.  I generally prefer the callback method, but again, either pattern is equally correct.

 

Here’s a simple example of how you can call this API so that it behaves correctly regardless of the number of storage devices the user has.

 

 

public class MyGameState

{

    public StorageDevice Device;

}

 

public class MyGame : Game

{

    protected override void LoadContent()

    {

        // Some object you want to have passed into the callback

        MyGameState myGameState = new MyGameState();

 

        Guide.BeginShowStorageDeviceSelector(StorageCompletedCallback, myGameState);

    }

 

    void StorageCompletedCallback(IAsyncResult result)

    {

        // Retrieve the state you passed in

        MyGameState myGameState = (MyGameState)result.AsyncState;

 

        // Complete the call and retrieve the selected StorageDevice

        myGameState.Device = Guide.EndShowStorageDeviceSelector(result);

    }

}

 

 

Hopefully if you’ve run into this problem with your games, you now have a better understanding of what is occurring, and how to fix it.

A lot has happened...
28 May 08 10:01 AM | mitchw | 1 Comments   

Since I last wrote about XACT compression over a year ago.  Let's see:

  • We released XNA Game Studio 2.0.
  • We've built a version of XNA Game Studio that will enable the Dream Build Play winners to publish their XNA Framework based games on Xbox LIVE Arcade.
  • GDC 2008 was interesting...
    • We announced Community Arcade games that will allow you to share your games over Xbox LIVE Marketplace.
    • We announced that XNA Game Studio 3.0 will add support for creating games for your Zune!
  • We released the XNA Game Studio 3.0 CTP in May, providing an early look at the new features coming out this year.
  • We released a beta of the Community Games support.  If you're an XNA Creators Club member, you can try it out today over at http://creators.xna.com!
  • Oh, and a completely new website too!

That's quite a lot for 12 months!  Right now we're cranking away at finishing up XNA Game Studio 3.0 and getting the Community distribution system ready to go later this year.  As for me, I'm primarily working on where XNA Game Studio is going beyond 3.0...what will 4.0 and 5.0 look like?  What are the problems that (still) exist for our customers who are trying to create great games?

And I'm working on a few presentations for Gamefest.  Oh, and I try to create some games too. :)

Audio Compression using XACT
27 April 07 05:25 PM | mitchw | 1 Comments   

There are two pieces of feedback that I hear quite a bit related to the audio support in XNA Game Studio Express.

  • It only supports WAV files. All of my sounds are in a different format, such as WMA.
  • Audio binaries are too large. WAV isn't compressed, so my music tracks are huge!

We're investigating what we can do for the first issue, which would obviously help the second issue at the same time. But there is some support for compressing your audio files in the current product, using the XACT tool; it's just not easy to discover. XACT supports ADPCM compression on Windows and XMA compression on the Xbox 360. You can get about 4:1 compression with ADPCM and even better with XMA. So while perhaps not as high as some other encodings, such as WMA, it does offer quite a substantial savings.

So how do you enable compression for your Wavebanks? Let's take a look:

  • Create an XACT project and a Wave Bank
    Start the XACT editor by using the Start menu shortcut Microsoft XNA Game Studio Express -> Tools -> Microsoft Cross-Platform Audio Creation Tool (XACT).  Create a new project and add a new Wave Bank to the project.
  • Add some WAV files to the Wave Bank
    While we won't be playing any sounds during this, we do want to see the results of the compression.  Once your done with this, you should see something like the below screenshot.

 

  • Create a new Compression Preset
    You can create a group of compression settings via a Compression Preset.  This allows you to reuse the settings across multiple Wave Banks.  This is also why it's a bit hidden.  Rather than adjusting the compression settings on the sounds themselves or the Wave Bank, we do it here.  You can create a new Compression Preset easily by right-clicking on the Compression Presets item in the explorer.

 

  • Tweak Settings
    After you've created it, you can see the default compression settings for ADPCM and XMA. You do have the ability to change some of these settings, although we'll just leave the defaults for this exercise.

 

  • Apply the Compression Preset to the Wave Bank.
    This is as easy as selecting the Wave Bank we created earlier, and then selecting the Compression Preset we just created in the Properties window for the Wave Bank. This tells the XACT compiler that we would like it to compress the WAV files using the preset settings when it builds the Wave Bank binaries.

 

  • Done!
    If we look at the details for the WAV files that are in the Wave Bank, we see that they now indicate they are compressed and how much space is saved.

 

I hope this was helpful for those that didn't know about the ability to compress your audio binaries using XACT.  While not as compressed as some other formats, it should provide for smaller game sizes, especially when including audio assets for background music.

XNA Framework Feature Question: Audio
26 April 07 02:34 PM | mitchw | 4 Comments   

The native XACT APIs have added the support for programmatic wave playback. I.e. at runtime, you can load *.wav files into a Wavebank and play them from there, without needing to create a project and compile the binaries.  This is something we're looking at supporting in our next release, but I want to gauge how much interest there is in this feature?  Keep in mind that implementing this feature may very well mean we can't do some other feature.

So how important is this to you? Is using the XACT editor and precompiling your audio a big issue? Is it just a learning curve for the editor, and then you move on?

Please vote here: http://forums.xna.com/7198/ShowThread.aspx#7198

XNA Game Studio Express 1.0 Refresh is Available!
24 April 07 09:32 AM | mitchw | 0 Comments   

As detailed here, we've released an update to XNA Game Studio Express today.  You can get an idea of what's in it by reading this announcement post.  The primary goal of this release was to get official Vista support into the product.  We also took the opportunity to fix a bunch of bugs and add a few new features.  Many of the bugs we've fixed and features we added came directly from you, so I hope you enjoy this release and thanks!

 Now on to the next release!

XNA Game Studio Express is available!
11 December 06 11:47 AM | mitchw | 0 Comments   

XNA Game Studio Express is now available for download.

http://msdn.microsoft.com/directx/XNA

This includes the Xbox 360 side of things as well. You can set up your Xbox 360 via the Xbox Live Marketplace.

So let's see what you got! Your game may even make it to Xbox Live Arcade!

http://www.dreambuildplay.com

XNA Happenings
26 October 06 09:52 AM | mitchw | 0 Comments   

You've probably seen the post announcing we're releasing a Beta 2 of XNA Game Studio Express.  This release contains lots of fixes and tweaks based on feedback and it includes the much anticipated Content Pipeline!  As we get closer to release, I'll have a post that explains some of the changes.

 If you want to get a sneak peak at what's coming in the beta, then you should stop by the Seattle Code Camp v2.0 that is happening this weekend.  There are a lot of great sessions, including 3 XNA related sessions:

  • Making an XNA Game for the Xbox 360
  • Introduction to the Programmable Pipeline in XNA
  • Exploring the XNA Framework

I'm giving the last session where we'll be looking at new features and changes in the XNA Framework, a little peak into the Content Pipeline and our support for the Xbox 360!

GO BUCKS!
10 September 06 12:14 AM | mitchw | 2 Comments   

Ohio State 24   Texas 7

 

Game.GameServices
06 September 06 09:54 AM | mitchw | 21 Comments   
I was originally going to create a tutorial that walks you through creating a custom GameComponent, perhaps the Framerate component from my demo or an event driven Keyboard component, but I’ve actually seen several of these pop up over the last few days so perhaps you’ve got the hang of it. J
 
What I have seen are a few questions about are game services and particularly IGraphicsDeviceService.  So I thought I’d write up a quick description of game services as well as the proper way to query and use the IGraphicsDeviceService.
 
GameServices
A game service can be thought of as a service that is available to anyone that has a reference to a Game.  The idea behind it was there are certain types, or services, that a component should be able to depend on for its functionality.  If that service isn’t available, then the component can’t operate correctly.  The first one we thought of (and one of the reasons behind introducing services) was making a GraphicsDevice reference available across a game.  Originally we had the Game own the GraphicsDevice and expose it via a property like Game.GraphicsDevice.  The problem with this was that this tightly bound the GraphicsDevice to the Game, not allowing someone else to “own” the device (such as a renderer) and preventing someone from using a future updated GraphicsDevice without shipping a new version of Game that wouldn’t be backwards compatible.  So to achieve the loose coupling of a GraphicsDevice and a Game, we factored the device management and ownership into a GameComponent, which is how GraphicsComponent came to be.  We still needed to make the GraphicsDevice available across a Game or even outside of the Game. As long as someone has a reference to a Game, they should be able to get a hold of a GraphicsDevice, if it’s available.  That’s the idea behind a game service.  The GraphicsComponent “publishes” an interface, IGraphicsDeviceService, as a service that others can query for and obtain a reference to.  In this sense, a service is a singleton that is keyed off the type of the service itself.  So a component that needs to render using a GraphicsDevice, doesn’t have to be tied to a GraphicsComponent, it can just query for the IGraphicsDeviceService instead.  Imagine if someone wanted to create a high-level renderer that owned the GraphicsDevice itself, rather than use the GraphicsComponent.  They could create the renderer as a GameComponent and publish an instance of the IGraphicsDeviceService themselves and now the Game has use of a new renderer and all game components that depended on a GraphicsDevice will still work too!
 
One other benefit of services is that Game.GameServices can be passed to the ContentManager so the type loaders in the content manager can query for services (this is how textures load for instance).  Because the container is passed one can add additional content types to the content manager (via a custom type loader) that relies on a custom game service without any intervention on our part.
 
So that was a quick explanation of a game service (complete with a GraphicsComponent history!) but it should help convey what the purpose of a service is and when you’d use them.  They really are meant to be a system wide service that something can query for.
 
IGraphicsDeviceService
As mentioned above, game components that wish to render something on the screen need to get a reference to a GraphicsDevice.  They could expose a property that is of type GraphicsComponent, but this would cause them to not work if a Game used something else to manage the GraphicsDevice, such as a custom renderer.  Instead a GameComponent that wishes to make use of the GraphicsDevice should query for the IGraphicsDeviceService from Game with the following line of code:
 
IGraphicsDeviceService graphicsService = Game.GameServices.GetService<IGraphicsDeviceService>();
 
Here’s what the IGraphicsDeviceService interface looks like:
 
// Summary:
//     Defines a mechanism for retrieving GraphicsDevice objects.
public interface IGraphicsDeviceService
{
    // Summary:
    //     Retrieves a graphcs device.
    //
    // Returns:
    //     A graphics device.
    GraphicsDevice GraphicsDevice { get; }
 
    // Summary:
    //     The event that occurs when a graphics device is created.
    event EventHandler DeviceCreated;
    //
    // Summary:
    //     The event that occurs when a graphics device is disposing.
    event EventHandler DeviceDisposing;
    //
    // Summary:
    //     The event that occurs when a graphics device is reset.
    event EventHandler DeviceReset;
    //
    // Summary:
    //     The event that occurs when a graphics device is in the process of resetting.
    event EventHandler DeviceResetting;
}
                                                             
As you can see the interface provides a reference to the GraphicsDevice as well as several events that you should use to properly detect when you need to load and unload your graphic resources such as textures, vertex buffers, index buffers and effects.  It’s also important to note that you should only cache a reference to the interface, not a reference to the GraphicsDevice.  This is because the reference to the GraphicsDevice can (and most likely will) change over the course of a Game due to window resizing, changing monitors, etc.  The reference to the service, however, will remain the same throughout the game.
 
So you should typically query for the service and hook up the events you care about inside of the Start method of a GameComponent like so:
 
public override void Start()
{
    this.graphics = this.Game.GameServices.GetService<IGraphicsDeviceService>();
   
    this.graphics.DeviceReset += new EventHandler(graphics_DeviceReset);
    this.graphics.DeviceResetting += new EventHandler(graphics_DeviceResetting);
    this.graphics.DeviceCreated += new EventHandler(graphics_DeviceCreated);
    this.graphics.DeviceDisposing += new EventHandler(graphics_DeviceDisposing);
 
    LoadContent();
}
 
And provide event handlers like so:
 
        void graphics_DeviceDisposing(object sender, EventArgs e)
        {
            ReleaseContent();
        }
 
        void graphics_DeviceCreated(object sender, EventArgs e)
        {
            LoadContent();
        }
 
        void graphics_DeviceResetting(object sender, EventArgs e)
        {
            ReleaseContent();
        }
 
        void graphics_DeviceReset(object sender, EventArgs e)
        {
            LoadContent();
        }
 
And lastly it’s a good practice to put your loading and unloading of resources into a couple of common functions:
 
        private void LoadContent()
        {
            this.font = new Font(this.graphics.GraphicsDevice, "Components", "Comic Sans MS_16");
        }
 
        private void ReleaseContent()
        {
            if (this.font != null)
            {
                this.font.Dispose();
                this.font = null;
            }
        }
 
So I hope this was a helpful explanation of what game services are, why they are important and also what the IGraphicsDeviceService is for and how to use it.  Please let us know what you think over at the XNA Framework forum.
Game Component Demo Is Up
01 September 06 05:11 PM | mitchw | 3 Comments   

I put my video for the Game Component demo up on the XNA Team Blog and forgot to mention it here.  Oops! :)

http://blogs.msdn.com/xna/archive/2006/08/31/734204.aspx

 

XNA Game Studio Express (Beta) is now available for download!
30 August 06 08:57 AM | mitchw | 3 Comments   

You can grab it here.

This is obviously a beta, so there are a few rough edges here and there that we are working on.  If you have how-to or general questions, please go to the forums at http://msdn.com/xna/forums/.  If you find a bug or would like to make a suggestion, please go to our Connect Web: https://connect.microsoft.com/site/sitehome.aspx?SiteID=226.  After you sign in with your Windows Live ID, click on Feedback. From there, you can choose to file a bug or offer a suggestion for XNA Game Studio Express and/or the XNA Framework.

I'm working on the recording of the component demos and that tutorial. More later!

:)

 

Getting closer...
29 August 06 07:45 PM | mitchw | 1 Comments   

Tommorrow (morning?) the beta for XNA Game Studio Express should be available for you to download!

I'm going to do a video capture of the Gamefest demos I did so you guys can get an idea of what the component model looks like and some of the things you can do.  Of course I expect to see way better components over the coming weeks from the community!  As mentioned earlier I'll also post a tutorial walking you through creating a component that displays the frame rate for your game.  Just drop it onto your game and you're done!

XNA Game Studio Express
28 August 06 02:40 PM | mitchw | 1 Comments   

So you've all probably heard by now what I've been working on.  It's great to finally be able to talk about this stuff.  It's really exciting to read the reactions and to see that a lot of people are interested in XNA!  Just a few more days and you'll be able to download our beta and start making games!

Last Friday I posted on our team blog details about the XNA Framework.  Once we release the beta I'll post some tutorials and samples on my blog, including some GameComponent samples.  Stay tuned!

Going to Gamefest?
28 June 06 11:55 PM | mitchw | 0 Comments   

The Gamefest website has been updated.  You can now register as well as get conference details and agenda.  I'll be giving the Creating Games with the XNA Framework talk.  It should be an exciting session with a deep dive into the XNA Framework and lots of demos and code!

More Posts Next page »

Search

This Blog

Syndication

Page view tracker