Modable games and XNB

When I used Monogame 2.x, I never bothered with xnbs and the content pipeline, instead just including my PNGs and OGGs as Content. I also never quite understood how to get it working.

With Monogame 3.2, it seems that my hands are tied. I understand that there is probably a performance boost in using the content pipeline. However, this clashes with my desire to create a “modable” game.

Let me explain by example. If I make a data-driven action RPG, I might create a monster called slime. I would need to keep, probably in a JSON file somewhere (so it’s easy to edit), the following information:

  • Monster class name (eg. Monster)
  • Sprite name (eg. slime.png?)
  • Stats (eg. strength, health)

This would be for all content in my main game. I’m worried about two use-cases:

  • Change the sprite on an existing monster
  • Create a brand new monster

It seems that, if I use the content pipeline, modders would need to create new (or modify my existing) XNB files. Adding new XNBs requires recompiling, I think.

How would I manage something like this? Is it technically feasible? I’m already expecting to give them some sort of DLL with interfaces and base classes that they would use to create their own classes.

When an XNB holds a Texture2D is just like any other picture format, except it’s uncompressed. You don’t need to recompile, but you need some kind of tool to convert pictures to XNB. For example you could distribute a PNG to XNB converter, which is just a stripped down version of MGCB (MonoGame Content Builder).

You can still use a JSON or XML. No need to compile those into XNBs.

You can still use Texture2D.FromStream() to load your PNG files and the various XML classes in the .NET Framework. You aren’t forced to use XNB files through the ContentManager. It’s a trade-off between directly loading a PNG and loading a more optimized texture through the content pipeline.

@KonajuGames can you provide me with a code sample or link to a page explaining how to do this? I tried contentManager.Load<Texture2D>(...) and it seems it automatically looks for the xnb extension. (Adding .png was a long shot, and it didn’t help.) I’m just going for Windows and Linux, so I’m okay giving up compression/optimization for this.

@Nezz I don’t think I understand. Even if I distribute my game with MGCB, for new sprites added after I ship, don’t the new XNBs need to be added to the main project as content and linked at compile time? Or can I simply drop them into the Content folder and they’re loadable?

using (var stream = File.Open("Content/YourTexture.png", FileMode.Read))
{
    texture = Texture2D.FromStream(Game.GraphicsDevice, stream);
}
1 Like

@KonajuGames thanks, I’ll try it

Thanks for your help @KonajuGames and @Nezz . It turns out XNB files aren’t linked; MonoDevelop (and I suppose VS) just copy them to the Content directory on build. I tried a proof-of-concept simple app where:

  • image.txt contains the name of a single image
  • In a new project, I compile a XNB with an image matching the name
  • At runetime, I load image.txt and create a Texture2D instance based on whatever filename is inside

It works. Given the choice of XNB or raw PNG, I think I’ll go with XNB, because I expect consumers of my game to be building Monogame code anyway (they need to link my API base classes / interfaces regardless).

Cheers!

Yes, XNB files are copied as content and that’s it.

If you want the user to generate XNB files, they’ll need the MonoGame pipeline tool and any dependencies it has. You’ll need to handle distributing this with your game (or mod tools package). For simplicity you might be better off going with raw PNG. As @KonajuGames said, the benefit of XNB is that you can handle texture compression to improve performance.

@Aranda yes, I get that. This is my thinking:

  • I want users to mod my game.
  • To mod my game, they have to write code that references my API projects.
  • To reference my API projects, they need to be able to build MonoGame shared libraries.

Therefore, I can expect them to already have access to (and probably know how to use) the pipeline tool. If not, I can always switch from XNB to raw PNGs later.