In this tutorial, we're going to cover how to load content into your game. We'll get into the details in a minute, but this is a piece of MonoGame that doesn't work nearly as well as it should. Basically, we're going to have to use a piece from XNA. We'll cover how you can build your content through XNA and move it over to use in your MonoGame projects.
I really wish this tutorial weren't so stinking complicated. Trust me, the rest of MonoGame is much easier to handle than this tutorial. Push your way through it, and it will be downhill from here. And ask questions on the troubleshooting page if you get stuck.
Take a deep breath, and here we go…
Content, Content Management, and the Content Pipeline
Let's start by defining a few terms. First, content is pretty much everything in your game besides the code. It's the 3D models, the fonts, the images, the sound effects, the music. To make a game, you're going to need content, and lots of it. These tutorials are not so focused on how you create your content. (I'd love to add some in the future, but it's way down the priority list right now.) But as we go through different tutorials, I'll point out some starting points to you, so don't stress too much.
Second, content management is the part of your game, game engine, and tool chain that takes your content from raw files to something usable in your game. Content management is not a trivial task. If you look at the credits for a high end game, you'll probably discover that the majority of people dealt with the content and the processing of the content, rather than just coding a game.
There are lots of different strategies for managing content when you're doing game development in general, but what XNA does (yes, I know this is the MonoGame section of my site) is uses the concept of a content pipeline. The content pipeline is something that you dump your raw art assets (that's just another name for content) into, and it passes it through various stages (which you can configure) and ultimately puts it into a form that you can quickly and easily use in your game.
If you've never tried to make a game without some sort of pre-made content management system, you may not really get a good feel for how much easier this makes your life. Let me just say that without something like this, you're pretty much dead in the water. You'd spend your first six months building something that can load all of your files, and by that point, you'll have just an image reader and a 3D model reader, and you'll be tired and frustrated with no game to show for it, and you'll give up and become a cashier instead.
Now where were we?
Right. MonoGame. So MonoGame is supposed to be an open source implementation of XNA that runs everywhere, and is generally more awesome than XNA. But for some reason, they decided that a content pipeline wasn't a necessary part of MonoGame. Or rather, it was something they could do later. They're hard at work on it right now, and we might see that sometime in the next few months. (Maybe fall or winter 2013?)
But for now, we're without a content pipeline, and that's a problem. A really big problem.
We'll need a workaround to hold us over. The recommended workaround is to push your content through XNA's content pipeline, and then dump it into your MonoGame project. It's less than ideal, but it works until there's a better option.
For the rest of this tutorial, I'll walk you through this process.
Creating an XNA Content Project
Because you need to use XNA's content pipeline, you'll need to have XNA Game Studio 4.0 installed. I cover this process in depth in an XNA-specific tutorial, but basically, you'll need to download Visual C# Express 2010, and then install XNA Game Studio 4.0 on top of that. So yes, you'll now have Visual Studio 2012 Express for Desktop and Visual C# Express 2010 both installed, plus MonoGame, plus XNA.
(It's at this point that some people just give up and use XNA and Visual C# Express 2010 since you've got to use it anyway…)
I should mention that if you've got the paid-for Visual Studio 2012 Professional or higher, it seems to have the ability to pull in XNA and MonoGame after everything is installed, so you'd be able to get away with only using the one program (though you'll still need to have both installed).
For the majority of people who are using the free express editions (that's me, most of the time), you're going to occasionally have to jump from one program to the other.
Once you've got Visual C# Express 2010 and XNA Game Studio set up, you're ready to make a content project.
If you've already got an XNA game, and you're just trying to port it to MonoGame, your XNA game solution will already have a Content Project. You'll be able to skip this step.
If you're building a game from scratch, you'll need to create a new project. But this is pretty easy to do. In fact, the easiest way to do this is to just create a new XNA game project, which will include a content project which you can then build and steal the final files from.
- Open XNA Game Studio/Visual C# Express 2010.
- Start the New Project wizard by clicking on File > New Project….
- Locate the Windows Game (4.0) template. If you look at the category hierarchy on the left, you should find it under Visual C# > XNA Game Studio 4.0.
- Give your project a name and press OK.
You should then see your new project open, which you can add content files to. This will create a solution with two projects in it. The first project listed is the XNA game project. For the most part, you'll be able to ignore this, since you're building a MonoGame project separately.
The second project is your content project. By default, it will end with the name Content, and also have (Content) in parentheses after the name. This second project is where you'll be adding files to in the next section.
Adding Assets to your Project
With an XNA content project set up, you can now add art assets to it. By default, XNA supports the following file types, and MonoGame should be able to take advantage of all of them as well:
|Content Type||File Types|
|3D Models||.x, .fbx|
|Textures/Images||.bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, .tga|
|Audio||.xap (an XACT audio project), .wma, .mp3, .wav|
Whatever content files you want to add, simply drag and drop them into the content project in Visual C# Express/XNA Game Studio.
You may find it useful to organize your content into folders. To add a folder, right-click on the content project (note that the top level element in the solution explorer is your "solution", which can contain multiple projects—the content project is the second item inside of that), and choose Add > New Folder.
It is probably also worth pointing out that you can add existing files this way as well, instead of just dragging and dropping them into the project. And for a few things, such as .spritefont and .fx files, you can choose Add > New Item… as well. We'll cover those in more detail as they're needed.
Note that there are ways to extend the content pipeline if it doesn't already import the file types you need, but that's really a discussion for another day. In all likelyhood, you won't need that right away. The current XNA content pipeline is good enough for many games.
Building Assets into .XNB Files
With your content project up and running, and with any files you want added, you're now ready to send them through XNA's content pipeline, so that you can use them in your MonoGame project.
This is pretty easy to do. Simply select Build > Build Solution from the menu. This can also be done with the keyboard shortcut Ctrl + Shift + B.
If you look in the lower left corner of the window, you should see a message that says Build succeeded. That tells you it worked.
You don't need to run the XNA game here to get your content built. You only need to build the project.
Moving .XNB Files to MonoGame
You've now sent your content files through XNA's content pipeline, and you're ready to pull them in to your MonoGame project. The first thing to do is locate the compiled art assets. These will all have the extension .xnb.
You should be able to find them in your XNA game's build directory. This will be something like [XNASolutionDirectory]/[XNAGameDirectory]/bin/x86/Debug/Content.
That is, look for it under the project directory, but then you'll look, specifically, in the bin directory of the main XNA game, as opposed to the bin directory of the content project.
(Visual C# Express 2010 will save all of the solutions you make at C:/Users/[Username]/Documents/Visual Studio 2010 by default.)
Take all of the files here and add them to you MonoGame project.
So now back over in Visual Studio 2012, you'll copy your content files into your project with the following steps:
1. In the Solution Explorer on the right side, find the Content folder and right-click on it.
2. Select Add > Existing Item…
3. Browse to find the files that were built in the other project (in Visual C# Express 2010, with XNA). As I stated a minute ago, your XNA project will likely be at C:/Users/[Username]/Documents/Visual Studio 2010/Projects/. From there, find the XNA project you created for your game. Then dig down into your solution folder (perhaps WindowsGame1 or whatever else you named it) then into your main project folder (again, WindowsGame1 by default, but not WindowsGame1Content) then probably under /bin/x86/Debug/Content. (I know… that's ridiculous how hard it is to get down to it.)
4. Select the compiled content files. These will have the extension .xnb. If you don't see the XNB files, you'll need to change the dialog to show All Files (*.*).
5. Click the Add button and you'll see the XNB file added to your project.
6. The final step is to tell Visual Studio to copy your XNB files to the output directory. By default, Visual Studio doesn't really know what you expect it to do with these files. What you need is for them to end up in the same place as your compiled game (the .EXE file) so it can use it when your game is running. To do this, select the .XNB file in the Solution Explorer on the right and in the properties window (lower right) change the Copy to Output Directory field to say Copy Always.
You've now got your content files pushed through XNA's content pipeline and added to your MonoGame project!
Unfortunately, any time you make changes to your content, you're going to have to update the XNA project, rebuild the XNA project, then copy the compiled .XNB files into your MonoGame project. That's really annoying, I know. But it's kind of what you're stuck with with MonoGame. But the good news is, this is the ugliest part of MonoGame. The rest of it will be prettier, I can virtually guarantee that to you.
You've now made it through the hardest part of MonoGame, and if you're still here, you're in great shape going forward.
Loading Content in MonoGame
OK, now we are on to the real interesting part. We are now going to use the content we just added. In other tutorials, as we talk about using each of the different kinds of content in turn, we will discuss this in greater detail. For now, though, we will just do something simple. Loading content in your game is always done in about the same way. Go to your LoadContent() method in your game, and add the following line (replacing <FileNameWithoutExtension> with the name of your file in quotes):
Texture2D image = Content.Load<Texture2D>("<FileNameWithoutExtension>");
A Texture2D object is simply a way of storing a picture. A texture is the computer graphics term for an image that you place on a 3D object, which is one of the most common ways of using an image. There are other ways to use a Texture2D object, as well. We will talk a little more about this in other tutorials. All we really need to do to load our content is call the function Content.Load(), with the name of the asset that we want to load. In the angle brackets ("<" and ">") we put the type of content that we are loading, which in this case, is simply a Texture2D as well.
You do not need to put the extension on the file! In XNA, you could not put the extension in. In MonoGame, you can, but I'd still recommend against it. As MonoGame's content pipeline progresses, if they make it more like the XNA content pipeline, you'll have to strip out the extensions, which won't be fun.
Also, if you have put your content in different directories, you will need to put the path to the file as well. For example, if our image was called Logo in a directory called Backgrounds, we would need to say:
Texture2D image = Content.Load<Texture2D>("Backgrounds/Logo");
Unloading Content in your Game
For a small game, you may not ever need to unload any content in your game. However, if you have a big game, you can't just keep loading more and more content and expect it to keep working. It is a good idea to unload unnecessary content whenever you are done using it. So, for instance, you can unload all of the content for a particular level, after the level is completed, so that there is room for the next level's content to be loaded.
To do this, simply add the following line to your program:
This frees up (almost) all of the content that was loaded by your content manager. Of course, this means that if you want to reuse something that was previously loaded, you will need to load it again.
It might be a good idea to create multiple ContentManager objects to divide up the content. That way you can call Unload() for the ContentManagers that you are done with.
Even if you don't have a big game, it is still doesn't hurt to unload unused content.
We've discussed how you can load content or art assets in your MonoGame project. This will make it easy to start working on your game, which we're now ready to do!
|Having problems with this tutorial? Try the troubleshooting page!|