Help replacing Content Pipeline with Content Folder?

can someone explain to me how to replace the content pipeline with a content folder?
for example I would just drop file into Content and at compile time monogame would embed them into the executable.

I found these posts but I’m not exactly sure how to combine them and use them.

It would be nice to have some sort of runtime alternative too for moddable content.
however it’s not necessary at the moment.

Personally, I think it’s better to build your content separately via the MonoGame Pipeline Tool, so that you’re always aware of exactly what it’s doing. You could use the steps below and still setup something in your .csproj file to build the content at compile time if you believe it’s necessary.

At any rate, this would involve a couple steps. First, the out-of-the-box content object in MonoGame is designed to read from file resources, so you’ll need to extend the class with something like this to read from embedded resources instead (untested code):

using System;
using System.Linq;
using System.Reflection;
using System.IO;
using Microsoft.Xna.Framework.Content;


namespace MyGameNamespace
{
	public class MyContentManager : ContentManager
	{
		private Assembly assembly = Assembly.GetExecutingAssembly();
		private string[] resourceNames = assembly.GetManifestResourceNames();


		public MyContentManager(IServiceProvider serviceProvider)
			: base(serviceProvider)
		{
		}


		public MyContentManager(IServiceProvider serviceProvider, string rootDirectory)
			: base(serviceProvider, rootDirectory)
		{
		}


		protected Stream GetResourceStream(string assetName)
		{
			try
			{
				Stream stream = assembly.GetManifestResourceStream(assetName);
				if (stream == null)
					throw new ContentLoadException("Resource not found");
				return stream;
			}
			catch (Exception exception)
			{
				throw new ContentLoadException("Error loading resource");
			}
		}


		protected override Stream OpenStream(string assetName)
		{
			return GetResourceStream("MyGameNamespace.Content." + assetName.Replace('\\', '/').Replace('/', '.') + ".xnb");
		}


		public string GetResourceText(string embeddedResourceAssetName)
		{
			using (Stream stream = GetResourceStream(embeddedResourceAssetName))
			{
				using (StreamReader reader = new StreamReader(stream))
				{
					return reader.ReadToEnd();
				}
			}
		}


		public bool HasResource(string embeddedResourceAssetName)
		{
			return resourceNames.Contains(embeddedResourceAssetName);
		}


		public string[] GetResourceNames()
		{
			return resourceNames;
		}
	}
}

Instead of using the out-of-the-box Game1.Content reference, you’d need to make a reference to this new class and make sure to implement its disposal. So, that would look something like putting this in the constructor of your game:

myContentManager = new MyContentManager(Services);

and this in your main game class:

// necessary since we're not using MonoGame's generic "Content" property - so we need to make sure our custom one hits its Dispose call as well
protected override void Dispose(bool disposing)
{
	content.Dispose();
	content = null;
	base.Dispose(disposing);
}

You could then use this new object in the same way as your default content loading:

Texture2D myImage = myContentManager.Load<Texture2D>("images/someCompiledImageAsset");

Now, you’d need to replace your actual Content.mgcb reference with something else that will collect your built content (XNBs and other files created by the MonoGame Pipeline Tool). To do this, remove your Content.mgcb reference from your project, and then edit your .csproj to include something like this:

<EmbeddedResource Include="..\..\MyGameProject\Content\bin\Windows\**\*.*">
	<Link>Content\%(RecursiveDir)%(Filename)%(Extension)</Link>
</EmbeddedResource>

It’s worth noting, that using a method like this, you’d need to reload your project (or VS) anytime you’ve added or removed a content file, since VS collects the files to be embedded at project load time.

Also noteworthy, in many cases, choosing to embed your content into your executable will often cause performance/loading issues.

Hopefully this will give you a good jump-start on using embedded content with MonoGame :slight_smile:

thank you for the reply.

is there a way around having to reload my project every time I add content?
also is there a way to pack all my xnb’s into a single xnb instead of embedded in the executable?

the main purpose of embedding resources in the application is so that xnb’s aren’t generated but instead resources are things like .pngs, .lua, .cfg, .wav

Where your content is (Embedded vs File Resources vs Etc) has nothing to do with what format they’re stored in. If you want your assets to be PNGs and such instead of Pipeline-Tool-built XNBs, just add references to those files in your project. MonoGame can read straight from PNGs in a few ways (check documentation). As for WAV and other assets, the way those are processed by your application is really up to you.