One of the biggest differences between the XNA content pipeline and the way many people are used to loading their game assets is that with the content pipeline, games no longer read directly from standard asset formats like .X, .BMP, and .FX. Instead, we process those files into a specialized binary format at the same time as compiling your game code.
The idea of processing assets during the build will be familiar to anyone who has worked on a console game, but may come as a surprise to people from a Windows background. There are actually several reasons why this is a good idea:
- Windows has a very rich programming environment with many helper programs and libraries that can be useful for loading and converting asset files. Most of these libraries are not available on Xbox, so the only way to get access to them is to pre-process the assets on a Windows machine.
- Game consoles only have limited amounts of RAM, and no virtual memory. Asset processing can need a lot of temporary memory, so it makes sense to run this on Windows during the build process.
- Converting game assets into a format that is ready to render can take a long time. If we did this work while loading the asset, it would slow down load times for everyone who plays the game. By moving processing operations to the build process, the developer only has to process the content once, after which it can be loaded nice and quickly for everyone who plays the game.
- By processing assets during the build, we can throw away any data that is not actually required by the game. This minimizes the size of the final game distributable.
- The more processing work is done during the build, the more errors can be reported up front, rather than only being spotted as a runtime crash when you later try to load that content.
But what if you need to convert content yourself, outside of XNA Game Studio Express? For instance what if you want to use the content pipeline in a level editor, or to convert user provided assets so that modders can extend your game?
You’re in luck, because all the content pipeline build functionality is exposed as an MSBuild task. I won’t go into details about MSBuild here (you can find more about it on MSDN, or using Google), other than to explain that MSBuild runs tasks as described by XML project files. In fact the .csproj files that you load into Game Studio Express are just a special kind of MSBuild project.
So to manually build content, you simply have to generate an MSBuild project that invokes the content pipeline, run it using MSBuild, and then load in the compiled .xnb files that will have been created for you.
Here is an example MSBuild project that uses the content pipeline to build a single file called MyTexture.tga:
<UsingTask TaskName=”BuildContent” AssemblyName=”Microsoft.Xna.Framework.Content.Pipeline, Version=18.104.22.168, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d” />
<XnaInstall>C:\Program Files\Microsoft XNA\XNA Game Studio Express\v1.0\References\Windows\x86</XnaInstall>
<PipelineAssembly Include=”$(XnaInstall)\Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll” />
<BuildContent SourceAssets=”@(Content)” PipelineAssemblies=”@(PipelineAssembly)” TargetPlatform=”Windows” />
If you save this XML into a file called test.proj, you can then run this from the commandline by invoking “msbuild test.proj”.