How should I use the MonoGame Pipeline Tool?

Let me level-set. I know very little about MonoGame and the way it should be used. On the other hand, I’ve been working with OpenGL since the mid-1990s, Open Rails, which uses XNA, more recently, and computer graphics in general since the late 1960s. Having had my first taste of success with a textured FBX model yesterday, I set out today to do some experiments to determine the way that the pipeline tool was meant to be used.

Between the tool’s Help documentation and Chamillard’s book “Beginning C# Programming with MonoGame,” I got the idea that one should use the pipeline tool to set up (Visual Studio) MonoGame projects. (I no longer believe that.) I did two experiments today that led me to how I will use the pipeline tool, at least until somebody tells me the RIGHT way to use it.

  1. I decided to try out creating a new project with the pipeline tool to see what it produced. I created a Test folder inside my Experiments folder. In the pipeline tool, I selected File/New, navigated to Test, and changed the default target filename from Tools.mgcb to MyTools.mgcb. I added a Content folder under MyTools and subfolders Models and Textures under MyTools. (Drag and drop is apparently not available in the tree pane.) With File Explorer, I copied an FBX model into Models. In the pipeline tool, I added the existing item to the Models folder. I saved the project and attempted to build it with the tool. It failed, not finding the texture image file referenced in the model. (I wanted to test using an unbuilt image file rather than an XNB file, just for academic reasons.) At this point, My project folder Test contains only folder Content and MyTools.mgcb. (It also contained a Textures folder that I mistakenly added outside the Contents folder. I deleted it in the pipeline tree pane, but that did not delete it physically.) At this point, I abandoned my intent to not create an XNB for the texture, and I physically moved the image file into the Textures folder with File Explorer, then added it in the tool’s tree pane. I did a File/Save and attempted a build. Two successes: the model and the texture. At this point, there is a bin folder and an obj folder in Test. In bin, there is a Content folder, with Models and Textures subfolders. In Models, there is an XNB file corresponding to my FXB model file. In Textures, there are two (I double-checked) XNB files, one corresponding to my single image file and one with a suffix of “_0” added to the filename portion. Where did this come from? (In my successful run yesterday, only one XNB was built in the bin Textures folder – the one with the “_0” suffix. In addition, the tool builds a shorter path to bin’s Contents folder. Starting from the project directory, the tool builds: Test\bin\Content. VS builds: Test\bin\Windows\x86\Debug\Content. In light of this, because of the apparent need to edit VS files (e.g., .csproj), I will set up my projects in VS first and use the pipeline tool as little as possible.

  2. I created a totally separate solution (Test2), project name, Game1, with VS. Project type: MonoGame Windows Project. I added Textures and Models subfolders to Content. I added my FBX file only to the Models folder. I built the VS project. But no content was built as output. At this point, I turned to the pipeline tool. I opened the Content.mgcb in my VS project. There was no content reflected. Nevertheless, I created the content file tree with the FBX model, but no image, which had not yet been added physically. I built the content. It failed with the expected notification that the image file referenced in the FBX file was not found. I physically moved the image file into the VS project’s Contents\Textures folder, but I DID NOT ADD IT IN EITHER VS OR THE PIPELINE TOOL. I went to the pipeline tool and built the content. Surprise 1: It reported one successful build (the model) and no failures. Surprise 2: I went to VS and ran the program. There was my textured cube. Surprise 3: I checked the bin path, and there were two XNB files, one in Textures (with the “_0 suffix) and one in Models.

I am not yet willing to draw conclusions, but I’m thinking that I should do as much work as possible in VS. But, when it comes to building content, I should use the pipeline tool. But, it is not necessary to Add image files (as items) in either the VS or pipeline tool Textures folders when they are referenced in a model file. The build process apparently resolves the reference and creates the XNB for the image.

In my opinion, the Help documentation for the pipeline tool is just not thorough enough for the edification of newbs like me. Just like with a hammer or saw, newbs need guidance regarding how to use the tool.

Walt

The Pipeline Tool is going through some development right now, but I’m sure this is on the roadmap.

If you have the texture in the same relative path to the model as it is set as in the fbx this should work (in this case it was probably “…/Textures/myTexture.png”, you can search for this in the fbx with a text editor or whatever 3d tool you used to build it). The Pipeline Tool will build the texture into an xnb too, and mangle it’s name a bit if you don’t add the texture with the Pipeline Tool itself to make sure no conflicts occur if you add another texture with the same name. That’s were the 0 suffix comes from. If you added the texture to the pipeline tool too it should not produce the xnb with a suffix, most likely it was already there. If you clear your bin and rebuild, only the non-name-mangled xnb should be generated.

The .mgcb file has an output path setting that determines were it spits out built xnb’s, by default this is /bin. so if you have the .mgcb file in the root directory of your project, it will generate it’s output in …/ProjectDir/bin.

The documentation on the pipeline tool is out of date a bit. I have a pull request up that updates the documentation and adds information on what’s currently the easiest way of handling content. Here’s a snippet of it:

  • The simplest method is to setup your game project from one of the
    templates that come with the SDK. When you create a new project it will
    include a Content.mgcb file with its Build Action set to
    MonoGameContentReference. This build action is defined in the .targets
    file here.
    MonoGameContentReference is set up so that when the project is built,
    the mgcb will build any new/modified content and copy the resulting
    xnb’s to the output directory so they can be used in the project. The
    content files do not need to be added to your project.

This is by far the easiest way of handling content. All you need to do is add it to the .mgcb. Added content will be built automatically and resulting xnb’s will be copied to the output folder of your project. There’s no need to manually add content to the project, just open Content.mgcb with the pipeline tool and add content.[quote=“Walt_Niehoff, post:1, topic:8013”]
Surprise 1: It reported one successful build (the model) and no failures. Surprise 2: I went to VS and ran the program. There was my textured cube. Surprise 3: I checked the bin path, and there were two XNB files, one in Textures (with the “_0 suffix) and one in Models.
[/quote]

If you could follow everything I said, you should get why this happened now. The texture was located relative to the fbx file as expected, so it could be resolved and built. It is not added to the .mgcb, so the name gets mangled because you’re not expected to load the texture seperately. It doesn’t matter if you actuallyadd it to the project, as long as the relative location is correct.

Yes, there is a lot of work to be done in documentation, but it’s a very tedious task which is why there hasn’t been a lot of progress lately. If anyone that knows enough about this is willing to contribute, that’s always welcome. I’m planning on contributing some more myself, but I have other contributions to MG planned (that are not related to documentation).

Hopefully this clears it all up a bit, if you have any questions or I didn’t explain well enough, feel free to ask. In fact, explaining this to someone by answering questions like this is a lot easier than writing documentation IMO, so if you ask enough, maybe we can copy-paste some stuff over to the docs :stuck_out_tongue:

Thank you for the very thorough response to my lengthy query. I read your reply several times and thought I mostly understood. Apparently there still are some missing pieces. Let me take one piece at a time, just to keep it manageable.

I took your indented and bulleted paragraph pair that starts with “The simplest method is … .” I created a new VS project with the “MonoGame Windows Project” template. I checked the Content.mgcb properies to verify that the Build Action was, in fact, MonoGameContentReference. I noted that the default Copy to Output Directory property was “Do not copy”. I did not change that.

A possible source of my confusion was your use of the word “project.” That doesn’t tell me the vantage point (VS or Pipeline Tool). I decided to take the VS meaning. That was okay for your first paragraph, but confusing for the second. I decided that, in the second paragraph I should take the pipeline tool vantage point because, in the third paragraph (un-indented), you say as much.

In the pipeline tool (launched by double-clicking the Content.mgcb in VS), I built parallel folders for Models and Textures. In Models, I added a correct (with “…\Textures<filename+ext>”) FBX file. Because I wanted to test a “no texture XNB” case, I added nothing in the Textures folder. I attempted to build the content with the tool. It failed, not finding the texture file referenced in the FBX. I checked the project’s Textures and Models folders. Nothing there.

Then, via the tool, I added the texture file to the Textures folder and rebuilt the content. Two successful builds. I checked the Models folder, and there was an XNB there. I checked the Textures folder, and there were TWO XNBs there, one with the name referenced in the FXB and the other with a mangling “_0” suffix. The code built and executed fine.

A further source of confusion is that there are two bin folders – one in root and one in Content. At the ends of both bin paths are parallel Models and Textures folders. The Textures folders both had two XNBs. I decided to delete the content of both Textures folders. Every time I did that, it executed perfectly, and there was no evidence in the VS output window of a rebuild.

I am thoroughly confused, but I must confess to not having a valid reason for wanting to not compile an XNB for a texture. Rather, it’s a sign that there’s something that I don’t understand, and that bothers me. However, I am able to continue working.

I did another test with a fresh new project. I changed only one thing: I loaded the tool’s Textures folder with my texture, from the start. The content built in the tool, and the code built in VS. It executed perfectly. Still, there were two XNBs (one unmangled and one mangled) in the Textures folders at the end of the path in both bins.

This is actually quite useful. The files in Content/bin are copied automatically to the output folder, which can be Debug, Release and so on. So if you have xnb files from another source (like an old XNA project), they can be placed in Content/bin and they will be automatically copied to the output folder as needed.

This should not be the case, can you share the files? I’ll take a look at this and fix it if needed.

Some clarifications:
When I said project I always meant the project from a VS point of view. So what is included in the project and is in the .csproj file. Not what is added to the .mgcb and not the actual folder/file structure.
When you build a .mgcb file it will produce a bin and obj folder where it is located ( can be changed, but this is the default). When you build a project in VS it will also produce a bin an obj folder. When build action of your .mgcb file is set to MGContentReference, that means that when you build the VS project, it wil build te .mgcb. If your mgcb file is in the projRoot/Content folder, this will produce the xnb’s in projRoot/Content/bin/Windows/ (assuming you’re building for Windows). Then it will copy all content of that folder to the output folder of your VS project with the location of the .mgcb relative to your project root appended. I.e. projRoot/bin/…/Content/ with … being platform, target and Debug/Release (if the .mgcb is in projRoot/Content.

Just a quick summary/recap, short and clear:

  • Building a .mgcb is in itself does nothing more than make xnb’s and put them in bin/{Platorm}/ relative to the .mgcb file itself
  • When loading content in the game with a ContentManager it should be in {GameExeLocation}/{ContentManager.RootFolder}. By default projRoot/bin/Windows/AnyCPU/Debug/Content/ (depending on platform, target and Debug/Release).
  • The MonoGameContentReference build action builds the .mgcb file and then copies over the pipeline tool output to the project output

I decided to give you the whole blessed VS project. Note that the two XNBs in bin\Windows\x86\Debug\Content\Textures are quite different in size. The unmangled one is 257K, and the mangled one is 86K. You can get the zip file here. The Test5 project is the last experiment I reported on. The model and texture source files are those of MSDN’s XNA Tutorial 1 (with the FBX file updated and hand-edited).

And thanks for the additional wisdom.

Walt

I’ll have a look tomorrow or this weekend, thanks! If there is anything left that’s not fully clear to you, please don’t hesitate to ask. These questions help me to type out some stuff that can go in the documentation later and will help other people too :slight_smile:

Take your time with it; I’ve got plenty to keep me busy here. Thanks for encouraging me – both implicitly and explicitly.

Walt

1 Like

I do have a new question this morning: Is the XNB output from the content pipeline available for use with OpenGL? How? (Examples are good.)

Note: I have no immediate need for the answers. I bring it up now because the answer(s) should probably be in the documentation.

Walt

Here is the procedure (for starting a new project) I worked out for myself in case I forget what I’m doing. It assumes a raw newb (like me).

In Visual Studio

  1. New Project. In the left-hand pane, expand C#. Then, in the right-hand pane select the MonoGame type. Fill in the project name, folder location, and solution name (if desired).
  2. Setup the VS project the way you want. Check that the Build Action for Content.mgcb is MonoGameContentReference, but avoid assembling content for now.
  3. You can load the source code if you want and build the project.

In MonoGame Pipeline Tool
4. To launch the pipeline tool, double-click the Content.mgcb icon in VS’s Solution Explorer. (This can be done less directly by launching the pipeline tool, clicking File/Open, and navigating your way to the Content folder in the VS project. Select the Content.mgcb file and click Open.)
5. Check the platform desired in the lower-left pane.
6. In the content tree view (upper-left pane), construct the desired folder subtree with one or more application of Add/New Folder.
7. Load the folders just added with content file(s) with one or more application of Add/Existing Item. (The content files may be anywhere.)
8. When you’re done with your Content tree, save the project with a File/Save.
9. Click Build/Build. This creates .xnb files in the project’s Content\bin\Windows\ folder tree. If all builds are successful, you may continue below.

In Visual Studio
10. With File Explorer, check to see that all the content filetree folders appear in the Content folder of your VS project and that the respective folders are loaded with copies of your source content files.
11. Check the Content\bin folder of your VS project (also with File Explorer) and, at the end of the path chain there, you should find duplicate content folders, but containing compiled content XNB files.
12. Build the VS project again.
13. Now, with File Explorer, check the end of the <project_root>\bin\ … <type (Debug or Release)>\Content\ chain for duplicates of your content folders. They should contain copies of your XNB files.
14. Finally, run the program.

It has been tested exactly once – by yours truly.

Walt

That sounds about right! Without the checking it boils down to

  1. Start a new project from a MG template
  2. Open Content.mgcb with the pipeline tool and add your content
  3. Build and run the project

Note that the platform that the mgcb gets built for is set correctly when starting from a template and your step 9 is unnecessary because te MonoGameContentReference build action triggers a build of the .mgcb

When does that occur? At pipeline tool Save time? When a content item is added?

When you build your VS project. That’s when the Build Action stuff gets done. In this case the .mgcb is built and xnb’s get copied to your project output folder

Thanks.

Could you suggest what might be causing this pipeline tool error message:

In my own musing, I speculated that it might be caused by improper handling of empty meshes in the scene tree. Empty meshes are used as collection elements. This Blender model has a bunch of them. Independently, I can introduce an empty node in my simple cube model tomorrow.

Walt

I don’t think this error has been reported before, I’d have to debug to figure it out. Let me know if you find something more. If you can also share a failing model I’ll investigate that too :slightly_smiling:

Wanting to test my hypothesis that my NullReferenceException might be caused by my use of an “empty” Blender object to serve as a parent for a group of child objects, I created a simple test case. It used a previously created (and MonoGame-successful) textured cube. I duplicated the cube. Lastly, I created an empty element and parented it to the two cubes, as shown in the screenshot below:

I exported the model as an ASCII FBX and updated that FBX with the FBX Converter. I hand-edited the RelativeFilenames in the FBX to represent the target directory convention. After building the projects and executing, the model looked just like it should. Another hypothesis goes down the tubes.

I’ve got another thing I want to try with the Blender model associated with the content build failure, but it will take me some time.

Walt

I cleared all of the Blender warnings during the FBX export, and the same NullReferenceException is issued by the MonoGame Content Pipeline Tool build. I put a copy of the project here in case someone wants to help with some diagnosis.

Walt

I’ll take a look when I have the time.

I didn’t take a look at your other issue (the duplicate texture in the output) yet, but the fact that filesize is different makes me think we can’t just switch out one with the other. I’m not sure what the difference is between the two though.

I’m continuing to work with Blender exports of FXB for the complex model (“Depot”, the one that causes the NullReferenceException), basically performing a binary cut-and-try. I had one successful content build of an export. However, the model was a leaf of the cut-and-try tree. It did write two XNBs there also.

I think it’s easier to just debug this