XNA Essentials

Game Programming for Xbox 360, PC + Windows Phone

NAVIGATION - SEARCH

Microsoft MVP Awarded July 1st

I’m pretty late to be announcing this. I can’t believe it has already been two months since I’ve received the award, but on July 1st, 2009 I received the Microsoft MVP Award in the area of XNA/DirectX.

MVP_Horizontal_FullColorI’m honored to have been awarded this. The main reason why someone is given the MVP award (less than 5,000 world wide currently have this award) is because of the work they do in their community.

Speaking in User Groups and Code Camps are the types of things that help someone get the award. Helping out with the local user group is a big plus. Even doing things like making sure the venue facilities are returned back to the way the group found them can be helpful. Finding a good place to meet monthly is challenging. The last thing the group wants to do is lose their facility. My local .NET User Group currently meets at Advanced Home Care, which is a great location. We meet the first Tuesday of every month. We will be meeting tonight, September 1st at 6:00PM. If you are near Greensboro definitely drop by. The great thing about User Groups and Code Camps is that they are absolutely FREE to attend. Yes, the folks that give their time to run the user groups and organize the code camps find sponsors who pay for the food, swag and everything else that goes into putting on these events.

Besides being active in my local user group and speaking there, I’ve spoken at a few other places including Burton Center for Arts & Technology near my hometown of Roanoke, VA. I gave three lectures one day to some middle schoolers and some high schoolers. It was an enjoyable day and the students seemed to enjoy the fact that games could be written for the Xbox 360 console.

Several years ago, I spent a lot of time in SecondLife. I created a few games in there and used to sell them. There is a .NET User Group in SecondLife where I’ve gave an XNA talk earlier this year.

While the PDC event was taking place last year, Chris Love, Rachel Appel  (who are both MVPs themselves) and a few others started up NotAtPDC. I was able to give an XNA talk using LiveMeeting. Giving talks online is definitely challenging because you can’t see the audience. You have no idea if you are connecting with them or not. Either way, I’ve enjoyed both and will probably do these types of events again.

Since you are on this site, you most likely know I’ve written a book on XNA game programming using XNA Game Studio. This also played a big part in me getting the MVP award I’m sure. There are some that think getting the award because you wrote a book is cheating because you already got compensated for the book. Typically (and my book is no exception) technical books do not bring the authors much money. But it can be argued that any money is still compensation and community work has no monetary rewards. Some don’t see any difference in putting time into a book that helps others, versus time into a website with Ads. Sometimes ads have made more money for folks than royalties from a technical book. Others tend to think that if work was done and you can be awarded for it multiple times then more power to you. That said, having the book alone wouldn’t have been enough. In fact, this was my second book. So having two books alone wouldn’t have been enough to be awarded with the MVP Award. It was the activity with the local user group and code camps and the speaking engagements.

On a side note, I found out last week that a college professor of mine (who taught several of my Computer Science courses including Graphics Programming) is using my Microsoft XNA Game Studio 3.0 Unleashed book this year for that class. There are other colleges and universities that use my book in different courses, but to have your old college professor use your book to teach a class he taught you is pretty surreal.

So here is the call to action for you my dear readers – yes both of you – you need to get plugged into some community activity. A great way to become a better developer is to surround yourself with better developers. A good way to do that is to attend user groups and code camps. Of course the other events like PDC, Mix, GDC and GameFest are good too – but there is usually travel costs plus the actual event cost which can make it prohibitive for some. With user groups and code camps which are free for the attendees there is no reason not to get out there and meet other developers and learn new things.

Happy Networking and Learning!

-Chad

Raleigh Code Camp – September 19th, 2009

If you are near the Raleigh, NC area on September 19th, 2009 you should really drop by the free Code Camp. If you have never been to a code camp, it is an event put on by a local user group. The events are free to the folks that attend. The folks that give their time to run the user groups and organize the code camps find sponsors who pay for the food, swag and everything else that goes into putting on these events.

If you aren’t in this area, you should definitely check around to see if there is a .NET User Group in your area. I attend one locally here in Greensboro, NC where we meet the first Tuesday of every month. We will be meeting tomorrow night, September 1st at the usual place.  The talk tomorrow night is on “Mashing up MVC, Bing, Maps and Flickr”. It should be good.

Again, it is really beneficial to get plugged into your local developer community. What better way than through events like User Groups and Code Camps?

The session list for the Raleigh Code Camp promises to have some excellent content. If you are interested in XNA you can hear me talk, but there are tons of other subjects that are interesting as well. There are talks on jQuery by Rachel Appel and Kevin Griffin, Database Design by Andy Leonard, Blend for Developers by Diane Wilson, LOB Apps with Silverlight 3 with Jim Duffy, general guidance on making high quality .NET applications with Chris Love, TDD with Steve Andrews, Dynamic Language Performance with Kevin Hazzard, UX in Silverlight with Rob Zelt and many others. The quality of speakers for this event is really great. I’m privileged to be speaking at the same event as these folks.

Again, to better ourselves as Software Engineers it is crucial for us to continue to learn. A great way to do that is to get with like minded people and User Groups and Code Camps provide an extremely cheap (FREE) way for us to connect with others.

Happy Networking and Learning!

Chad

Dream Build Play 2009 Challenge Submissions Due Today

Make sure that you get your XNA Game Studio 3.1 game submitted to the contest today. Show Microsoft what you have been working on for the last 4 months or more. Grand prize is $40,000. Do not wait until the last moment to try and upload your game. Head over to http://www.dreambuildplay.com/ and submit your game now!

Hope everyone does well!

If you submitted your game to the DBP competition and want to show off your work, feel free to post in the forums. The forum is also for any XNA work that has been done. Make sure to read the Showcase Guidelines before posting.

Happy Sharing!

-Chad

Advanced Debugging Tutorial – Part Two

In the first tutorial we talked about some of the advanced debugging techniques. In this tutorial we will take it a step further and create a debugger visualizer. When we look at data while debugging, sometimes the default representation isn’t quite good enough. For example, the value of a Matrix variable is displayed as simply a string. We could make it into a table structure that actually represents the Matrix. We could also actually display the real color instead of just the color name or RGBA values.

In this tutorial we will be creating a color visualizer. When creating a debugger visualizer there are a few steps that have to take place. We need to do a few more things to get the visualizer be a Windows form that utilizes XNA.

image

Typically one would do the following steps to create a normal visualizer:

  1. Create a class library projects
  2. Add appropriate references (Microsoft.VisualStudio.DebuggerVisualizers; System.Windows.Forms)
  3. Create a class and make the class inherit from the abstract class DialogDebuggerVisualizer
  4. Override the Show method from the abstract class
  5. Add the assembly attribute DebuggerVisualizer setting the appropriate properties
  6. Copying the compiled assembly into one of two folders so Visual Studio can load it and use it

We will be altering the earlier steps a little since we are going to start off with a Creators Club Online Educational Example. We want our windows form to actually utilize XNA and there is no reason to reinvent the wheel. Let’s get started!

Start with the Educational Example: WinForms Series 1: Graphics Device

Extract this to a new folder called XNAVisualizer

Rename the project to XNAVisualizer

Rename the solution file to XNAVisualizer.sln

Open the solution file and rename the project in the Solution Explorer

Rename all of the namespaces to XNAVisualizer.

A shortcut for renaming all of the namespaces is to change one name and then click on the dropdown it makes and select “Rename ‘WinFormsGraphicsDevice’ to ‘XNAVisualizer’

image

Change the project type from Windows Form to Windows Library.

Double click on the Properties node in the Solutions Explorer. Under the Application tab change the Output Type from Windows Application to Class Library

image

While we have the properties window open, we can change the Assembly Name to XNAVisualizer

Delete the SpinningTriangleControl from the project.

Rename SpriteFontControl to ColorControl

We will be adding this control to the form later. This is the control that will display the color being debugged.

Add the following public field to the new ColorControl

public Color BackgroundColor = Color.CornflowerBlue;

Change the contents of the ColorControl’s Draw method to contain:

GraphicsDevice.Clear(BackgroundColor);

spriteBatch.Begin();
spriteBatch.DrawString(font, BackgroundColor.ToString(), new Vector2(10, 10), Color.Black);
spriteBatch.DrawString(font, BackgroundColor.ToString(), new Vector2(11, 11), Color.White);
spriteBatch.End();

In the Initalize method replace the following line:

content = new ContentManager(Services, "Content");

with these three statements:

Assembly visualizerAssembly = Assembly.GetExecutingAssembly();
content = new ContentManager(Services);
content.RootDirectory = visualizerAssembly.Location.Replace(
    visualizerAssembly.ManifestModule.Name, @"Content\"); 

Since this assembly will be running in a special folder we need to explicitly tell it where it can find the Content assets. We are using the Arial font from the original project. We are displaying the Color’s RGBA values using the font. The code is using reflection to get the executing assembly (our visualizer) and then setting the path to the path of the assembly and appends Content\ to the end of it. The Location property contains the full path including the assembly name (XNAVisualizer.dll). The ManifestModule.Name contains the assembly name as well. We are simply removing the assembly name from the path.

Since the code is using reflection we need to add the following using statement to the top of our ColorControl.cs file:

using System.Reflection;

 

Now we can bring our attention to the MainForm.

Remove all controls from the MainForm form

Double click on the MainForm.cs file

Click Ignore Errors and Continue

Remove the combo boxes, the split panel and delete each one. You may have to right click on the form and choose Select ‘spltContainer1’. Once it is selected you can hit the Delete button on the keyboard to remove it.

Make the form itself a lot smaller. For this we are simply wanting to display the color and the RGBA values of the color so it doesn’t need to be too large.

Compile the project and double click on the error to bring us into the MainForm.Designer.cs. Remove the SpinningTriangleControl and vspriteFontControl variables.

Remove the vertexColor_SelectedIndexChanged method from the MainForm class.

Remove the three vertexColors from the MainForm constructor.

Recompile to see 0 errors.

Open the design view of the MainForm again.

Re-add the ColorControl directly to the form by dragging it from the toolbar (under XNAVisualizer Components)

Expand the ColorControl so it fills up the entire form.

Change the form’s FormBorderStyle in the properties panel to FixedToolWindow. This keeps the window from being resized.

Change the Text of the window to “XNA Color Visualizer”

Drag the ColorDialog (from the toolbox under either the All Windows Forms or Dialogs tabs) to the form. This will create colorDialog1.

Double click on the ColorControl to create the _Click event.

Replace the contents of the MainForm class with the following:

public MainForm()
{
    InitializeComponent();
} 

public XnaColor Color
{
    get
    {
        return (colorControl1.BackgroundColor);
    }
    set
    {
        colorControl1.BackgroundColor = value;
        colorControl1.Invalidate();
    }
} 

private void colorControl1_Click(object sender, System.EventArgs e)
{
    if (colorDialog1.ShowDialog(this) == DialogResult.OK)
    {
        Color = new XnaColor(colorDialog1.Color.R, colorDialog1.Color.G, colorDialog1.Color.B, colorDialog1.Color.A);
    }
}

We added a public property Color. The example code declared XnaColor as a type to help distinguish from the XNA Color and the Windows Form Color. We are using the XnaColor type. We simply return the BackgroundColor of our colorControl when Get is called. And for Set we, we set the background color of the control as well as Invalidate our control so it will be redrawn. We could have hooked into the Idle event and called Invalidate continually, but there is no need for this control. The original example does this with the SpinningTriangleControl. Reading the WinFormsGraphicsDevice.htm file would be beneficial to see the pieces of the code we are using but not discussing like GraphicsDeviceControl, GraphicsDeviceService and ServiceContainer.

We populated the colorControl1_Click method by actually displaying the built in Windows Color Dialogbox. If the user clicks OK, we get the selected color from the dialog box and set our color property to the newly selected color. Our color property then sets the BackgroundColor property of the ColorControl. Note: This control does not let us change the Alpha value of the color.

 

The last thing we need to do is actually create our Visualizer code.

Add a new blank code file and name it ColorVisualizer.cs.  Paste the following code:

using System.Diagnostics;

using Microsoft.VisualStudio.DebuggerVisualizers;
using Microsoft.Xna.Framework.Graphics;

[assembly: DebuggerVisualizer(
    typeof(XNAVisualizer.ColorVisualizer),
    Target = typeof(Microsoft.Xna.Framework.Graphics.Color),
    Description = "XNA Color Visualizer")]

namespace XNAVisualizer
{
    public class ColorVisualizer : DialogDebuggerVisualizer
    {
        protected override void Show(IDialogVisualizerService windowService,
                                     IVisualizerObjectProvider objectProvider)
        {
            Color c = (Color)objectProvider.GetObject();

            using (MainForm form = new MainForm())
            {
                form.Color = c;

                windowService.ShowDialog(form);

                if (objectProvider.IsObjectReplaceable)
                {
                    if (form.Color != c)
                    {
                        objectProvider.ReplaceObject(form.Color);
                    }
                }
            }
        }

    }
}

We have to add a reference to the Microsoft.VisualStudio.DebuggerVisualizers assembly by clicking on the References tree node in the Solution Explorer under the XNAVisualizer project. Making sure we are on the .NET tab we scroll down and select the assembly and add it to our references.

The assembly attribute DebuggerVisualizer tells VisualStudio this is the entry point for the visualizer. It tells it what type of data it is visualizing as well as the description.

The visualizer class itself inherits from the DialogDebuggerVisualizer abstract class. We override the Show method to actually display our form with the data being investigated by the debugger. We look at the objectProvider object passed in and cast it to our Color type. We set the Color property on the MainForm to the value we are debugging. We then actually display the MainForm by calling ShowDialog on the windowService object passed in.

If all we wanted to do was display the color we would be done. However, it would be nice to actually change the color on the fly while debugging. This is why we added the Color Dialogbox. We first check to see if the object we are viewing is replaceable. It won’t be replaceable, for example, if we are debugging an enumerated type (i.e. Color.Black). However, if it is a variable holding a value then it will be replaceable and we replace the object by calling ReplaceObject on the objectProvider object passing in our new object (form.Color in this case). There is also a ReplaceData method, but we aren’t discussing that in this tutorial.

After compiling the assembly we need to place it in one of two directories:

\$Documents\Visual Studio 2008\Visualizers

or

\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers

Since we have Content assets we also want to copy the Content folder and any assets to the Visualizers folder as well. It can be tedious to copy the assemblies and content assets after every compile. We can create a Post Build Event command line to copy it for us. We need to open the properties of the XNAVisualizer project (by double clicking on the Properties node in the Solution Explorer) and go to the Build Events tab. Click on the Edit Post-build button and paste the appropriate variation of the following command and hit OK:

copy "$(TargetPath)" "C:\Users\<User Name>\Documents\Visual Studio 2008\Visualizers"
md "C:\Users\<User Name>\Documents\Visual Studio 2008\Visualizers\Content"
copy "$(TargetDir)\Content\*.*" "C:\Users\<User Name>\Documents\Visual Studio 2008\Visualizers\Content"

(Change the paths as needed)

Now when we run a regular XNA project and we want to debug the color we simply set the breakpoint and when we hover over the color variable we want to debug we click the Magnifying Glass icon which will bring up our newly created form.

Fortunately, the XNA Framework team did a lot of the heavy lifting for us (as usual) in this example by allowing us to utilize XNA in a Windows Form. We simply modified the example to be a Class Library and added the actual Visualizer code.

Debugging the Debugger Visualizer

To debug a debugger visualizer a static test method can be created and then a console app can be created to call the static method. This can be a great way to test the visualizer. Instead of creating a console app with all of the XNA assemblies referenced, I debugged the visualizer by  attaching to another Visual Studio instance.

In the Debugger Visualizer project click on Debug / Attach to Process. A dialog will come up. Select Visual Studio instance you want to debug. This would be your real XNA project that has a XNA Color variable.

image

Now when we set a break point in the main XNA project and hover over a Color variable and hit the magnifying glass it will kick off the Visualizer Debugger and if we had a breakpoint we could step though the code. Pretty cool!

 

A great next step would be to create another visualizer in this project to display Matrices.

For more reading on Visualizers look in the following here.

Download the code from this tutorial here.

Happy Coding!

-Chad

Xbox LIVE Indie Games

It is official! Xbox LIVE Community Games is now Xbox LIVE Indie Games. The name change will be reflected on xbox.com and Xbox LIVE Marketplace later this summer.

The name change isn’t the only thing happening. The prices options for the games are being changed. The days of listing a game for 800 points (about $10 USD) is coming to an end. To me, it was really difficult for a Creator to compete against expansion packs, and XBLA titles anyway. The new price points will be 80, 240 and 400.

On the Creators Club Online site itself there is a new shiny thing called Reputation. The idea is great and hopefully it will inspire Creators to review and test more games. More information about Reputation can be found here.

Upgrades to Xbox LIVE Indie Games will now be automatic! So if you push out an update to your game, the gamer will be asked if they want to download the most updated version of the game. Very cool!

Also, now Creators get a maximum of 50 tokens for their games. This will allow the Creator to give media outlets an easy way to review their game.

New Countries can now submit Indie Games – Germany and Japan. There are also updates for Sweden and Singapore.

For a complete list of the changes see the official story on the XNA Creators Club Website.

There is no time like the present to create your dream game. Get to it!

Happy Coding!

-Chad

XNA Game Studio 3.1 Avatar Tutorial

Microsoft XNA Game Studio 3.1 was released today and as a result I had to get my hands dirty with the avatars. I've been waiting on this since August of last year when I heard about NXE and went to GameFest where I saw how the native Xbox developers could make calls to render the user's Avatar.

I've followed Dean Johnson's blog where he has written a few entries about the avatar system. I was really looking forward to it. Things at my day job have been pretty hectic recently and I've been putting in some late hours - reminds of when I was writing the book - so if this tutorial isn't up to snuff, I'll come back and edit it. But for now, I wanted to get the information out there for people to be able to start playing with this cool feature.

The end result of what we will be building is a quick demo that allows the user to generate a random avatar and cycle through pre-built animations of our own avatar.

Preview

 

Let's get started!

This tutorial is going to assume you know how to draw 3D objects and use a camera. I won't be discussing those items here. This is purely to get going with displaying the 3D avatars. I used code from chapter 6 in my books as a starting point. It has it's own camera and input classes. The 2.0 code for that chapter is available on my downloads page.

We need to declare the following member fields that will store our randomly generated avatar data:

AvatarDescription avatarDescription;
AvatarRenderer avatarRenderer;
AvatarAnimation avatarAnimation;

 

Next, we can add in the member fields that will store our own avatar's data:

AvatarRenderer personalAvatarRenderer;
AvatarAnimation personalAvatarAnimation;

 

We can also store the current animation of our personal avatar:

AvatarAnimationPreset currentAnimation = (AvatarAnimationPreset)0;

 

We just set the default animation to the first one in the AvatarAnimationPreset enum.

Then inside of the constructor we set the backbuffer width and height. I set it to 1920 x 1080 since that is the display connected to my Xbox 360.

graphics.PreferredBackBufferHeight = 1080;
graphics.PreferredBackBufferWidth = 1920;

graphics.ApplyChanges();

 

 

I then added my own FirstPersonCamera and InputHandler game components (feel free to use your own):

input = new InputHandler(this, true);
Components.Add(input);

camera = new FirstPersonCamera(this);
Components.Add(camera);

 

It is very important to include the GamerServicesComponent so we can obtain the avatar information:

Components.Add(new GamerServicesComponent(this));

 

In the LoadContent method we can add the following:

avatarDescription = AvatarDescription.CreateRandom();
avatarRenderer = new AvatarRenderer(avatarDescription);
avatarAnimation = new AvatarAnimation(AvatarAnimationPreset.Clap);

font = Content.Load<SpriteFont>(@"Fonts\Arial");

We are obtaining the description of the avatar by calling the CreateRandom method. We then take the description and apply it to the actual renderer. Finally we initialize an animation that we will use later. (We also are going to display the name of the animation our personal avatar will be doing so we added the font.)

Now we can add the following logic to our Update method (You can substitute your own input handler code):

PlayerIndex playerIndex;

if (input.WasPressed(null, Buttons.A, Keys.Space, out playerIndex))
{
    avatarDescription = AvatarDescription.CreateRandom();
    avatarRenderer = new AvatarRenderer(avatarDescription);
}

if (input.WasPressed(null, Buttons.B, Keys.B, out playerIndex))
{
    currentAnimation++;
    if (currentAnimation >= AvatarAnimationPreset.MaleYawn)
        currentAnimation = (AvatarAnimationPreset)0;

    if (personalAvatarAnimation != null)
        personalAvatarAnimation = new AvatarAnimation(currentAnimation);
}

avatarAnimation.Update(gameTime.ElapsedGameTime, true);

if (personalAvatarRenderer == null)
{
    foreach (SignedInGamer gamer in SignedInGamer.SignedInGamers)
    {
        personalAvatarRenderer = new AvatarRenderer(gamer.Avatar);
        break;
    }

    personalAvatarAnimation = new AvatarAnimation(currentAnimation);
}

personalAvatarAnimation.Update(gameTime.ElapsedGameTime, true);

 

We check to see if the user pressed the A button. If so, we generate a brand new random avatar. If they press B then we increment the currentAnimation value, reseting to zero if we get to the end of the enum values. The .NET Compact Framework on the Xbox 360 doesn't support Enum.GetValues so we will simply convert to an integer to iterate through them.  We then change the animation playing in our personal avatar to our new value.

We then call update on the random avatar, passing in the elaspsed time and true which means we want to loop this animation.

If the personal avatar hasn't been created yet, then we grab the first signed in gamer (this could definitely be more robust) and pass in the gamer's Avatar description to the AvatarRenderer. We also initialize the animation for the personal avatar. Finally we call update on the personal avatar also telling it to loop.

 

All of this is fine, but we haven't actually drawn anything to the screen. We can correct that now by adding the following code to the Draw method:

avatarRenderer.World = Matrix.CreateRotationY(MathHelper.ToRadians(180.0f)) * Matrix.CreateScale(10);
avatarRenderer.Projection = camera.Projection;
avatarRenderer.View = camera.View;

avatarRenderer.Draw(avatarAnimation.BoneTransforms, avatarAnimation.Expression);


if (personalAvatarRenderer != null)
{
    personalAvatarRenderer.World = Matrix.CreateRotationY(MathHelper.ToRadians(180.0f)) *
        Matrix.CreateTranslation(new Vector3(3, 0, 0)) * Matrix.CreateScale(10);
    personalAvatarRenderer.Projection = camera.Projection;
    personalAvatarRenderer.View = camera.View;

    personalAvatarRenderer.Draw(personalAvatarAnimation.BoneTransforms, 
        personalAvatarAnimation.Expression);
}

spriteBatch.Begin();
spriteBatch.DrawString(font, currentAnimation.ToString(), new Vector2(20, 20), Color.Black);
spriteBatch.DrawString(font, currentAnimation.ToString(), new Vector2(21, 21), Color.Yellow);
spriteBatch.End();

 

We set the World, View and Projection matrices on the avatars. Based on my camera and world settings, I scaled the avatar by 10 units. We then actually call the Draw command passing in the bone transforms and the avatar expression so it knows how to draw the avatar.

We finish up by drawing the current animation to the top left of the screen.

The XNA Framework team did a fantastic job of providing avatar functionality that is extremely easy use. They also exposed ways to work with data at a more lower level. I hope to see some really awesome avatar games!

Final Result

Happy Coding!

-Chad

XNA Game Studio 3.1 is Released

XNA Game Studio 3.1 includes many cool features. They could have gotten away with a major version number in my opinion.  It includes things such as

Avatar Support

Xbox LIVE Party Support

Video Playback

Changes to the Audio API

Content Pipeline Enhancements

XACT3 Support

Also, it allows targetting either XNA GS 3.0 or XNA GS 3.1 inside of Visual Studio. XNA GS 3.1 games can be submitted to the peer review service on July 23rd.

Also, it appears the artist formerly known as XBLCG (Xbox LIVE Community Games) is now known as XBLIG (Xbox LIVE Indie Games).

More information can be found at http://creators.xna.com/en-us/news/xnagamestudio3.1

The download link is at the bottom of page. So download it today and start making 3D Avatar games with cool video billboards!

 

Happy Coding!

-Chad

Advanced Debugging Tutorial - Part One

In order to make games or any application these days it really helps to understand how the debugger works in your IDE. Since this site is all about XNA and specifically XNA Game Studio and the XNA Framework our IDE of choice is Visual Studio / Visual C# Express. For this series the majority of the tips are only available in Visual Studio (denoted by *). This series is going to discuss some cool tips and tricks for debugging our applications. Let's get started ...

Simple Breakpoints

Setting a break point is pretty simple by either clicking in the "Gutter" on the IDE or hitting F9. Doing this will toggle the breakpoint to be present or not.

image

Also we can display debugging information in the output window inside of the IDE. For example, if we use the following code:

System.Diagnostics.Debug.WriteLine("This is my debug message.");

We can see the results printed in the Output window of the IDE:

image

If we want to leave a breakpoint location, but want to disable it we can right click on the breakpoint and choose Disable Breakpoint. (Take note of the other options as we will be discussing them a little later)

image

After the breakpoint is disabled it is represented by a circle:

image

This can be beneficial as well, but we can do better than basic breakpoints and glorified printf statements.

Advanced Breakpoints*

Now we can get to the meat of the tutorial! The first thing to note is that it is best to start the debugging before setting up advanced breakpoints. It is not required, but the benefit is that the symbol tables are available instead of only Intellisense.

The Advanced Breakpoint image  allows setting a hit count, a condition or a filter.

Hit Count

To set a hit count, simply right click on a basic breakpoint and select "Hit Count" from the context menu. The following dialog will be displayed:

image

The code will execute skipping over the breakpoint until that line is called 1,000 times.

Here are the options available from the Breakpoint Hit Count dialog box:

 image

The first option, "break always", describes a basic breakpoint where anytime that code is about to be executed we break into the code.

The second and last options are easy enough to comprehend as the code will only break when the code has been executed a certain number of times.

The third option, "break when the hit count is a multiple of", can be thought of as a modulus calculation. If we used the value 60 for example, then we are asking the compiler to break execution every 60th time the code is executed. For XNA Games this could break the code once a second assuming we were running at 60fps and the break point was in the appropriate method.

Condition

Not only can we specify a hit count for our advanced breakpoint, but we can also specify a condition.

image

Just as the description reads, this will evaluate the expression entered and will only break if the expression is true or if the expression has changed. An interesting thing to note here is that it actually executes code. For example, if we were in a for loop with a typical index variable of i we could actually cause an infinite loop if we were not careful. In C# we do comparisons by using a double equal sign (==). A single equal sign (=) is used for setting values. So if we wanted to break when our for loop indexer i hit 20 but we put i=20 in the box then every time the compiler executed the expression it would actually set our variable i to 20 effectively causing our for loop to last forever (assuming the condition to break out of the for loop is when i is greater than some value over 20). So be careful to actually use a comparison operator.

An expression can be as simple as a variable. We could simply put in "i" (without quotes) and set the "Has changed" radio button. This would break the execution whenever the variable "i" had a value change.

Methods could even be called from this window. An entire debug class could be created that checks values for nulls or whatever is required. So something like DebuggerHelper.CheckValue(someValue) would be valid assuming that CheckValue returns a boolean type.

Filter

We can also set break points on certain machines, processes and/or threads.

image

For this dialog, even in C# using a single equal sign is allowed. Fortunately, the typical double equal signs is also allowed. Assuming our application had multiple threads (which can be helpful for long running content loads, etc) we can break the code only when we are in a particular thread. In this example it is assumed we have a thread created and we explicitly named it "SomeWorkerThread". When any other thread executes the code we have set this breakpoint on, the code will not break. However, as soon as the thread we specified hits the code the execution will be paused.

Stepping through threaded code can be aggravating since stepping through the code will jump all over the place if we do not know how to ignore other threads. Fortunately we can do this by making sure our debug toolbar is visible by selecting it from the View > Toolbars > Debug menu item:

image

This will bring up the following toolbar:

image

To view the other threads while debugging our code we can select the "Show Threads in Source" button image

Using this toolbar we can also open the Breakpoints window by clicking the "Breakpoints" button image

This brings up the following window where we can more easily manage our breakpoints:

image

By clicking on the Columns button we can add the columns we want. By default Hit Count, Filter and When Hit are not displayed.

OK, back to our threading issue...

First it would be nice to see all of the threads in the app. Well just like our Breakpoints window we can bring up the Threads window by clicking Debug > Windows > Threads or pressing CTRL + D, T

 image

We can see which piece of code our threads are in here. Remember by clicking the image button we can see the current location of the running thread by looking at the "Gutter" in the IDE (the same area where the breakpoint icons are displayed).

image

The last thing to note about Advanced Breakpoints is that Hit Counts, Conditions and Filters are ANDed together. So all conditions need to be met to actually break into the code.

Debugging .NET Framework Source Code*

Sometimes it can be beneficial to actually break into the .NET Framework source code when debugging. Yes, there is Reflector, but you can't exactly step into the code and you can't see the comments. Stepping into the .NET Framework code can be beneficial when some operation is failing (like the system saying a file doesn't exist when it definitely appears it does). By stepping through the code it may actually show that it is really an access denied error.

In order to enable the .NET Framework source stepping simply by going to Tools > Options and checking the "Enable .NET Framework source stepping" check box under Debugging / General as shown below:

image

After getting the dialog box that "Just My Code" is no longer selected you will see another dialog box talking about symbols. To get to the location simply click the Symbols tree node under Debugging.

image

You then need to add the following symbol locations:

http://referencesource.microsoft.com/symbols

http://msdl.microsoft.com/download/symbols

Then in the "Cache symbols from symbol servers to this directory" enter a permanent folder such as:

c:\dotnetsymbols

The next time you debug you will get a dialog box with a EULA for the source code.  Instead of only downloading pieces of the framework as you are working on it you may want to download all of it at once. This can especially be helpful if you work offline. There is a codeplex project, NetMassDownloader, that does just that.

Evaluation Windows

While discussing breakpoints we touched on the evaluation of breakpoint conditions. This evaluation functionality is also available in a few other windows as well.

Locals, Auto and Watch Windows

You can add particular variables to the Watch window. The Locals and Auto windows are populated / depopulated based on the scope of the application. You can click in the Value column and modify the value. This doesn't only work for value types but it also works for reference types. For example the texture greyAsteroid has a value assigned to it, but I am redefining it at runtime by typing in Content.Load<Texture2D>(@"Textures\asteroid1") in the Value column and pressing enter.

image

It is also legal to just create a new object. For example entering new SomeClass() would be a valid entry for the appropriate variable.

There is a little know feature called Make Object ID*. Simply right click on the row with a reference type and select Make Object ID.

 image

It will then associate an object id, for example {1#}, to the object. Since both my greyAsteroid and originalAsteroid variables are both member fields I knew they wouldn't go out of scope so I created a temporary test variable. When I create an Object ID for this variable I now have the following:

 image

Now the benefit of creating an Object ID is that I can see the memory even after it goes out of scope. I just need to type 1# as a new Watch item. Doing this and then stepping out of the method gives me the following results:

image

Notice the test object is out of scope and it is grayed out. Yet, I still have access to the object id. I can continue to look at the memory until the garbage collector runs. I'm not guaranteed how much longer it will be around, but this can be handy in advanced scenarios.

We can even check to see what generation the of the garbage collector the variable is in. We can add GC.GetGeneration(1#) in the Watch window and see the following result:

image

That is pretty cool!

Immediate Window

For the command link junkies there is the Immediate window. This is actually my favorite window. Just like the others you can evaluate expressions. You can also create new objects that you can evaluate at runtime. For example, you can type in

? SomeClass x = new SomeClass();

And then in the Watch window you can watch the value by entering $x.  Now not only can we set simple value types like bool, int, float, etc but we can create a new reference type and then set a value in our code to that new reference while debugging. This can also come in handy.

By the way, ? comes from the Visual Basic days and is short hand for print.

Summary

We discussed basic breakpoints, advanced breakpoints with filters, hit counts and conditions. Hopefully there was information in here that you didn't know existed. This can really help speed up development.

Well that is enough information to think on for this blog post. In the next installment I will walk through creating a Visualizer for Visual Studio.

* Not available in Visual C# Express

Happy Debugging!

Chad

XNA Essentials Web Site Upgraded - Hello Real Forums

I finally was able to spend some time this weekend to give this website the attention it deserved. I have installed Community Server 2008.5 SP2 and am now running the site with that. I have configured the site to only utilize a single blog. The biggest pain was trying to make sure all my old links still worked in the new site. The bits that took the longest were making sure the links at the root level still worked. Fortunately, it seems everything is working just fine.

We now have Forums! No longer are people required to use the Amazon forums. It seems that really wasn't ideal because of the different countries. This should work much better.

The blog entries actually have comments. Currently the two tutorials I have on the site are custom pages, but I think I will either convert those into a blog entry or into forum posts so there can be comments on them. The original website did not have anyway for the users to communicate to me or each other. Community Server corrects this.

Hopefully there aren't any outstanding issues, but if so I'll try and correct them as soon as possible.

Happy surfing!

Chad

Microsoft XNA Game Studio 3.0 Unleashed Source Code Available

The publisher is allowing the entire contents on the CD that are included in the book to be purchased. This option is available to people who that purchased the Kindle version of the book. For Safari subscribers, the code can be downloaded via Safari. The code can be found on the downloads page.

-Chad