Category: Programming

Porting a Game from XNA 4.0 to MonoGame 3.0 for Windows 8 Store

It’s fairly certain that Microsoft won’t be supporting XNA for non-Windows Phone platforms, so I decided to take some time to port my game to MonoGame. Just recently, the MonoGame team has released MonoGame 3.0 which includes full support for the Windows 8 Store. Follow these meager instructions to get yourself started with doing that. If you’re lucky like I was, there’s a chance that your code is almost a 100% carry-over to the MonoGame libraries.

  1. Download MonoGame 3.0 Installer
  2. Create New MonoGame Project for Windows 8 Store
    • Using Visual Studio 2012, create a new MonoGame project under Visual C# –> MonoGame –> MonoGame Game
  3. Manually Copy Code and Change References
    • Make sure MonoGame is referenced using the Windows 8 lib at C:Program Files (x86)MonoGamev3.0AssembliesWindows8MonoGame.Framework.Windows8.dll
    • Copy classes and files to the new project so that it mirrors the hierarchy of your XNA 4.0 project
    • Any libraries that are referenced which were compiled against the full .NET Framework will need to be recompiled against the .NET Core Framework (a subset of the .NET Framework that Windows Store Apps will reference)
    • Compile and fix any errors generated because of references to things that are no longer supported by Windows Store
    • Copy serialized .xnb files manually to the output directories of your MonoGame project (this is required because the Content Pipeline is not supported in Visual Studio 2012)

Some of the errors that I got were references to Close() method calls on streams (removed in .NET Core) and setting DTD validation on XmlStreams (also removed in .NET Core). See the link in the references section for an overview of the changes in .NET Core. Also, MSDN will have little green bag icons next to anything that is supported in the Window Store.

References:

http://msdn.microsoft.com/en-us/library/windows/apps/br230302.aspxRead more

How to get supported display modes using SharpDX

Below is a short bit of code that will use SharpDX to enumerate the valid display modes on all adapters (video cards) and all outputs (monitors) for the computer that is hosting the application.

There are a few caveats with this:

  • Do not run this if you are using the Windows RT device simulator from Visual Studio 2012 or you will get exceptions (remote/virtualized instances aren’t supported by some of the DirectX used here)
  • This only shows interlaced and scaling display modes (there are Stereo and StereoDisabled modes for some outputs)
  • Keep in mind that this is every adapter and output on your computer, so if you want just the default adapter, you’ll have to make some changes
  • Windows Store Apps are always in full screen, so any display mode that you apply to the active device where the resolution is less than the desktop resolution is going to look stretched (there are reasons to do this, however)
SharpDX.DXGI.Factory1 dxgiFactory = new SharpDX.DXGI.Factory1();
foreach (var dxgiAdapter in dxgiFactory.Adapters)
{
    foreach (var output in dxgiAdapter.Outputs)
    {
        foreach (var format in Enum.GetValues(typeof(SharpDX.DXGI.Format)))
        {
            var displayModes = output.GetDisplayModeList(
                (SharpDX.DXGI.Format)format,
                SharpDX.DXGI.DisplayModeEnumerationFlags.Interlaced
                | SharpDX.DXGI.DisplayModeEnumerationFlags.Scaling
            );

            foreach (var displayMode in displayModes)
            {
                if (displayMode.Scaling == SharpDX.DXGI.DisplayModeScaling.Unspecified)
                {
                    int displayWidth = displayMode.Width;
                    int displayHeight = displayMode.Height;
                    Rational displayRefresh = displayMode.RefreshRate;
                }
            }
        }
    }
}

References:

Read more

Why did my application fail Windows Store Certification?

I just finished watching a presentation on a broad overview of how to setup a Windows Store Developer account and submit applications to the store for certification and sale. Here are some guidelines that I found useful to follow in order to minimize the chances of having your application rejected during certification. The speaker noted that you will most likely fail certification for the first time, especially if it’s your first submission. Annoying, but I guess things have to be very specific to succeed.

1. The application must function in full

  • You must provide a test account for any required logins in the “Note to Testers” fields
  • Your application must not consist primarily of “Coming Soon” and “To be released later” content
  • Your application submission details must not contain false information or false screenshots
  • Your application must allow the user to control audio properly

2. The application needs to meet performance guidelines

  • Your application must launch in <= 5 seconds
  • Your application must suspend in <= 5 seconds

3. The application may or may not require a privacy policy

  • If your application indicates that it requires internet connection, you need to add a privacy policy in the application’s settings and provide a URL during submission

4. Your application must be localized as defined in your app manifest

  • Application chrome and content
  • Application metadata
  • Any and all screenshots and promotional images

All of this information was found from the slides presented in the Build 2012 presentation: “Windows Store: how does it work?”… Read more

Making Sense of Windows Store Developer Accounts

I found it rather annoying having to dig through pages of documentation regarding publication of Windows Store Apps just to figure out what kind of account I needed to create. So, here’s a quick table to see the comparison at an extremely basic level.

Individual DeveloperCompany DeveloperEnterprise DeveloperOEM Developer
DreamSpark / Student Account CapableX
Submit Modern UI (aka Metro, aka Windows Store) Apps to the Windows StoreXXXX
Submit Desktop Apps to the Windows StoreXXX
Create Account with SSN (US only)XIf registered as Individual
Create Account with EIN (US only)XIf registered as CompanyX

One other thing to note is that Individual Accounts cannot use the following “app capabilities.”

Reference: Publishing your app to the StoreRead more

My Forked TiledLib Project

If you’ve used the TiledLib library by Nick Gravelyn, you’ll agree that it’s super useful and easy to understand when working with maps from the Tiled editor. Unfortunately, Nick is no longer actively developing the library, so I have created a forked copy on Bitbucket. If you’re interested in following the progress of changes I make, feel free to follow the project. I most likely won’t be making sweeping changes, but I have noticed a few bugs in the provided map processor classes. So, my plan is to slowly add some more complex examples to the map processor such as collidable tile properties and object layers.

Original Project: https://bitbucket.org/nickgravelyn/tiledlib

Tiled Map Editor: http://www.mapeditor.org/Read more

2D Circular Motion

Just a quick post today about implementing circular motion in a 2D environment.

centerX = &lt;center X coordinate&gt;;
centerY = &lt;center Y coordinate&gt;;
radius = &lt;radius of circle&gt;;
speed = &lt;time to complete full circle in seconds&gt;
speedScale = (0.001 * 2 * Math.PI) / speed;
angle = &lt;game time in milliseconds&gt; * speedScale;

xCoord = centerX + sin(angle) * radius;
yCoord = centerY + cos(angle) * radius;

position = new Vector2(xCoord, yCoord);
  • Set centerX and centerY to the center of the circle (coordinates that you want your entity to move around)
  • Set the radius of the circle
  • Set the speed at which the entity should complete a full circle in seconds
  • Set the position of the entity to the results of the speedscale, x-translation, and y-translation

As time goes from 0 to 2*Pi and back to 0, the motion will complete a full circle.… Read more

Resolution Independent 2D Rendering in XNA 4

When I first started making my game, I hard coded the screen resolution to 800 x 600 for simplicity and built my menus and levels with the assumption that the screen was exactly 800 pixels wide and 600 pixels high. This was a mistake because all of my UI positions, tile positions, and entity placements were based on absolute positions and did not look proper when the resolution changed. If the user wanted to use a screen size that was not 4:3 and super tiny, the game looked completely wrong and was unplayable because the level layout was all over the place.

To solve this, I used David Amador’s Resolution class to introduce a means of rendering my scenes independent of the actual resolution of the window. I maintained an “internal” or “virtual” resolution of 1280 x 720 (Xbox standard) to be used for position of all my entities and UI elements. This virtual resolution never changes. Users can then adjust the “actual” resolution of the game which determines the real window size. We use a scaling matrix to transform the virtual resolution to fill the actual resolution with additional letterboxes or pillarboxes depending on the virtual and actual resolutions. I suggest you read the linked article from David Amador to understand the class and how to use it.

Changes for XNA 4

David’s article is what really counts when it comes making this work. However, it was written pre-XNA 4 and requires a minor change. Calls to SpriteBatch.Begin() require more parameters in the overload that allows for a transform matrix. The current method of using David’s code to scale your virtual resolution up to the actual resolution is:

spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, Resolution.getTransformationMatrix());

Obviously, your needs will dictate the exact parameters, but this is the overload you need to use at the very basic level.

Transforming Mouse Coordinates

Another problem you’ll run into is when trying to use mouse coordinates to interact with the elements of your game. The transformation matrix is applied only to the sprite rendering and does not affect the state of the mouse cursor. For example, using a straight up MouseState.GetState() will return coordinates in terms of the actual resolution and not the virtual resolution. Since your game is working in terms of the virtual resolution, this behavior is wrong!

Luckily, one of the commentors in David’s article explained a way to transform mouse coordinates into the virtual screen space. Here is a simple static abstraction that I created to get mouse position in terms of virtual resolution.

First, add two static members to the Resolution class.

static private int virtualViewportX;
static private int virtualViewportY;

Second, assign values in the ResetViewport() method.

viewport.X = (_Device.PreferredBackBufferWidth / 2) - (width / 2);
viewport.Y = (_Device.PreferredBackBufferHeight / 2) - (height / 2);
virtualViewportX = viewport.X;
virtualViewportY = viewport.Y;

Third, expose the values in public properties.

public static int VirtualViewportX { get { return virtualViewportX; } }
public static int VirtualViewportY { get { return virtualViewportY; } }

And finally, create a static MouseHelper class (or whatever you want) that has a way of getting the mouse position and translating it into virtual coordinates for you.… Read more

Simple Deserialization with XML and XNA Content Pipeline

The XNA Content Pipeline can at first seem daunting but is extremely easy to use once you get the hang of it. I wanted to share a small class that I created to represent an enemy entity that has its information stored in an XML format. The content pipeline reads my XML animated sprite data and imports/processes it to a .xnb file at build time. At run time, this .xnb file is then deserialized into an object that I can use to draw to the screen.

My XML content looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
    <Asset Type="ContentPipelineExtensionLibrary.EntityData">
        <CollisionOffset>0</CollisionOffset>
        <HorizontalSpeed>1</HorizontalSpeed>
        <VerticalSpeed>1</VerticalSpeed>
        <SpriteIdle>Sprites/Enemy/SimpleIdle</SpriteIdle>
        <SpriteMove>Sprites/Enemy/SimpleMove</SpriteMove>
    </Asset>
</XnaContent>

The C# class associated with this data at run time looks like this:

namespace ContentPipelineExtensionLibrary
{
    public class EntityData
    {
        public int CollisionOffset;

        public float HorizontalSpeed;

        public float VerticalSpeed;

        public String SpriteIdle;

        public String SpriteMove;
    }
}

The XNA Content Pipeline has a built in importer and processor for XML –> Object deserialization. As long as you have the “Type” attribute of the “Asset” element set to the correct namespace and class, the Content Pipeline will take care of the rest. Just load this content like so:

EntityData enemy = content.Load<EntityData("SimpleEnemy");

Reference: http://msdn.microsoft.com/en-us/library/ff604979Read more

Quirks with XNA ContentManager Load and Unload

I was recently experimenting with game state transitions and attempting to unload content when a screen was no longer needed. For example, I had a main menu screen which loaded assets to its own ContentManager on activation and unloaded the content when the screen transitioned off based on user input. This all worked fine until the main menu was asked to transition back on after the user was done playing the game.

What I found is that calling the ContentManager’s Unload method will call the Dispose method of all the resources for which it is responsible. You do not and should not manually call the Dispose method for content that has been loaded. However, a problem arises when you want to reuse something that has been unloaded without reinitializing the ContentManager. Even worse, the problem arises even if you call the Load method for a piece of content after it has been Unloaded.

For example:

Texture2D texture = content.Load&amp;lt;Texture2D&amp;gt;(&quot;texture&quot;);
content.Unload();
texture = content.Load&amp;lt;Texture2D&amp;gt;(&quot;texture&quot;);

spriteBatch.Begin();
...
spriteBatch.End();

I received an error on line 7 of the above paste because even though I reloaded the texture, the ContentManager will return the cached version of the already loaded texture (even though you called Unload!). Yes, the cached version is the one that got disposed!… Read more

Build XNA Game Installer: Visual Studio Setup Project

This guide assumes:

  • Visual Studio 2010 Professional
  • XNA Game Studio 4.0
  • Users will be Windows

This is the second article about building an XNA game installer when you are ready to distribute your game to the masses. In the first part, I described how to use the convenient ClickOnce option to build a relatively simple and non-customizable deployment package. If the ClickOnce option is too restrictive for you or simply does not meet your needs then you should refer to this article about using a Setup Project to create a more customizable installation package.

As with most things in life, the Setup Project is not a perfect solution to packaging up and distributing your game. What I find extremely annoying and shortsighted on Microsoft’s part is that the Setup Project will not automatically detect your game content like ClickOnce does. I want to be clear that, in this context, “content” is referring to your compiled content by the Content Pipeline (textures, sounds, other files) and not the “content” of your project as a whole. I will explain how to force the Setup Project to use your game content. Be warned: it is tedious and annoying, but it works..

  1. Open your game solution
  2. Right click solution -> Add -> New Project…
  3. Other Project Types -> Setup and Deployment -> Visual Studio Installer -> Setup Project
  4. Right click the setup project -> Properties
  5. Change the “Configuration” drop down to whatever configuration you want the setup to use (debug/release/etc)
  6. Click “prerequisites”
  7. Make sure these are checked:
    • Microsoft .NET Framework 4 Client Profile (x86 and x64)
    • Microsoft XNA Framework Redistributable 4.0
    • Windows Installer 3.1
  8. Right click the setup project -> View -> File System
  9. In the “Application Folder”, right click -> Add -> Project Output
  10. Change the “Project” drop down to the main game project
  11. Click “Primary” output in the list box
  12. Choose the configuration for which you want to include the output (debug/release/etc)
  13. Repeat steps 9-12 for any other projects that you need to include in the output (custom libraries)
    • NOTE: Do note include output from content pipeline extension projects because the content pipeline it is unavailable at run time

You just created a setup project, told it which prerequisites are needed for your game to work, and finally told it which build output you want to include in the installer. You can arrange the “File System” folders to how you see fit for your application folder hierarchy. For example, you should see options to include files in the User’s Desktop or the User’s Programs Menu in case you want to include shortcuts. Be careful not to abuse this though, because the user will not be happy if you dump 500 files on their desktop!

While that was relatively painless, all is not well in setup project land. For some reason there is no way to have the setup project automatically find your compiled content in .xnb format after the content pipeline has imported and processed your content files. You can include the “Project Output” of the content project, but that will not do anything useful, so do not bother!… Read more