Build MonoGame Content on Linux and CI with MGCB
Use the headless MonoGame Content Builder to compile XNB assets on Linux or in CI, then load them with ContentManager—no Windows GUI required.
14 Oct 2026, 01:36 UTC

The missing content problem
You clone a MonoGame 2D project on a Linux build server, run the tests, and the game crashes before the first frame with ContentNotFoundException. Locally everything works because you used the MonoGame Content Pipeline GUI on Windows to generate .xnb files. On Linux or in CI, that GUI does not run, so the binary content was never compiled or was left out of the deployment package.
The useful takeaway: treat content compilation as a first-class build step. Run the headless MonoGame Content Builder (MGCB) from a response file, ship the resulting XNBs with your executable, and load them at runtime with ContentManager.
What XNB and ContentManager actually do
MonoGame does not usually load raw PNGs or WAVs at runtime. The content pipeline converts source assets into .xnb files, a binary format optimized for fast deserialization and GPU upload. ContentManager is the runtime type-safe loader that reads those XNBs by asset name, without the file extension. If the XNB is missing, renamed, or built for an incompatible MonoGame version, the loader throws.
Worked example: build content from the command line
Create or maintain a .mgcb response file that lists each source asset, its importer, and its processor. A minimal file looks like this:
# Content/Content.mgcb
# Placeholder structure; exact keys depend on your MGCB version.
/outputDir:bin/Content
/intermediateDir:obj/Content
# Example entries
/content:Content/textures/player.png
/importer:TextureImporter
/processor:TextureProcessor
/content:Content/audio/jump.wav
/importer:WavImporter
/processor:SoundEffectProcessor
Run the builder where your CI runner has access to the source tree:
# Run in the terminal or CI job, not inside the game process.
# Required permissions: read access to Content/, write access to bin/Content/.
mgcb /build:Content/Content.mgcb /outputDir:bin/Content
Replace mgcb with the executable name provided by your MonoGame installation, such as MonoGame.Content.Builder.exe under Mono or the .NET-based builder if your distribution provides one.
Expected check: after the command finishes, bin/Content should contain player.xnb and jump.xnb. If a source file is deleted but still referenced in the response file, the build can fail or leave stale output, so re-run the builder whenever assets change.
Load and verify at runtime
In your game, load by asset name without the extension:
using Microsoft.Xna.Framework.Content;
// ...
var playerTexture = Content.Load("textures/player");
var jumpSound = Content.Load("audio/jump");
A practical diagnostic is a startup smoke test that attempts to load every critical asset before the first draw call and logs any ContentNotFoundException. This turns a mysterious black screen into an explicit list of missing files.
Limitation: XNBs are version-coupled
The XNB binary format is not guaranteed stable across MonoGame versions. After a major MonoGame upgrade, recompile all assets; do not copy old XNBs into a new build. Also, MGCB on Linux or macOS may require Mono or a compatible .NET runtime, so verify the builder executable starts on your runner before adding it to CI.
Closing checklist
- Commit the
.mgcbresponse file to version control. - Add a CI step that runs MGCB and copies
.xnbfiles to the output directory. - Deploy XNBs alongside the executable, not only source assets.
- Run a startup load test for one asset of each type and confirm no
ContentNotFoundException. - Recompile content after every MonoGame major version change.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.