MonoGame Content Pipeline XNB Compression

After porting my game from XNA, I noticed when doing a release build that the package was much bigger than it used to be. Turns out this is due to the xnb files (texture files in my case).

In XNA, the content pipeline will build raw RGBA files in debug, but it will do a lossless compression on them when building in release. In MonoGame, it seems like there is no debug/release option when building with the content pipeline tool, so I always get the uncompressed xnb file sizes.

Is there any way to build the compressed xnb files using the MonoGame content pipeline? Note: I’m not looking for DXT compression or any other form of lossy compression.

Thank you!

Yeah, my content has ballooned from 150 mb to 680 mb after migrating too.
One spritesheet now takes up 160 mb when deployed, in XNA it was 12 mb.
All of the model textures have tripled in size as well.

The spritesheet bitmap is stored as a PixelBitmapContent<Color>. Should the sprite sheet processor compress this data? If so, how…?

This is the SpriteSheet class:

    public class SpriteSheet
            // Single texture contains many separate sprite images.
            public Texture2D texture;


This is the corresponding SpriteSheetContent class, which is output from the processor:

public class SpriteSheetContent
        public  Texture2DContent Texture = new Texture2DContent();

Should I replace Texture2DContent with DxtXBitmapContent? I would prefer not to do lossy compression or anything that degrades the quality of the spritesheet.

How was compression in XNA achieved for Release mode? Does anyone know?

There are two types of compression that can be used here. Texture compression is things like DXT where the texture itself is compressed and loaded into GPU memory in the compressed state. Then there is XNB compression where the XNB file itself is compressed and uncompressed at load time.

DXT is a lossy compression format, and depending on whether your texture has non-opaque alpha values or not, it will give you 16:1 or 8:1 compression. File compression used LZX compression in XNA and we use LZ4. This is decompressed on load, so the small XNB will then occupy the full amount in memory.

Did your XNA XNB use texture compression or file compression?

Thanks for the reply.

In XNA, the sprite sheet xnb file was:
Release: 11mb
Debug: 64 mb

In MonoGame, it is now:
Release: 161 mb
Debug: 161 mb

I haven’t changed the sprite sheet processor and didn’t use DXT compression before.

The difference between Release and Debug in XNA may have been that XNB file compression was enabled in Release builds. As for the 64MB -> 161MB difference between XNA and MonoGame generated files, I would need to see samples of both XNB files and any custom content pipeline code to determine the reason for the difference.

I changed the Normalized byte format to Vector4 format in the normal map that is part of the spritesheet.

Will it be possible to invoke the XNA compression on the xnb file? Do we even know what technique was used to achieve it?

NormalizedByte4 takes four bytes per pixel, while Vector4 is 16 bytes per pixel. That will explain a large chunk of the difference.

To enable XNB file compression, select the top-most (project) node in the Pipeline tool and change the Compress property to True.

Great. After enabling compression, the size is now 21 mb.

Since compression was default in XNA (at least for release builds), shouldn’t it be the default in MonoGame also?

It may have been enabled by default, but only on Windows. On Windows Phone it wasn’t, and I can’t say what the default was for Xbox 360.

We do not currently have an easy way to build content differently between Debug and Release builds. The benefits and drawbacks of compressing content must be evaluated on the target platform. You would not want content compressed on Android because asset files are compressed by default as part of the Android packaging process, though this could be modified (exclude .xnb files from asset compression and use MonoGame’s content compression).