[solved] Couldn't find a default importer for .tmx files

I’m trying to use the Content Pipeline to add a .tmx files. But I get the following error when I build:

Couldn't find a default importer for 'C:/Projects/Content/level1.tmx'!

I looked around but I found nothing to help me.

This is what I have done so far:

  • I’m on Visual Studio Community 2017
  • I have a .NET Framework 4.7.2 project
  • With the following NuGet packages
    ** MonoGame.Extended v3.7.0
    ** MonoGame.Extended.Content.Pipeline v3.7.0
    ** Everything else is up to date
  • I add MonoGame.Extended.Content.Pipeline reference to MonoGame Pipeline Tool (Content.mgcb)
    ** /reference:..\..\packages\MonoGame.Extended.Content.Pipeline.3.7.0\lib\netstandard2.0\MonoGame.Extended.Content.Pipeline.dll

And when I build I get an error. I’m going crazy :smile:
I also try with .NET Core 2.0 with Visual Studio 2019. But the same …

Does anyone have any ideas?
Thanks in advance.

What version of the MonoGame Content Pipeline tool are you using?

I’m using MonoGame Pipeline Tool 3.7.1.189

This error has cropped up from time to time and it’s still unclear to me exactly why it happens.

I believe there’s some quirky thing going on in the MonoGame Content Pipeline.

My general recommendation is to make sure you’re using the latest version of MonoGame (most importantly the Pipeline Tool) because I think the bug exists there. However, every time someone reports this issue the symptoms seem to be slightly different so it’s quite confusing.

Presumably you are using the latest version so to be honest I’m not sure.

Other reporters of this issue have told me that it randomly went away after a while.

Maybe the next thing to do is to create a project that has the problem and I’ll see if I can reproduce it. Would you be willing to take the time to do that?

I don’t think that the bug exists on MonoGame (the Pipeline Tool).

As I said, I’m using the latest version of MonoGame (3.7.1). I just downloaded on this page last Monday. And I created a new project with the latest package of MonoGame.Extended.Content.Pipeline (v3.7.0). And I used that reference in the Pipeline Tool but it didn’t worked.

And today I cloned the MonoGame.Extended project and build v3.7.0 (git checkout v3.7.0) with Visual Studio. And I used that reference instead of the NuGet package annnnnnd it worked ! I also tried the master and it worked.

Nothing has changed expect the reference MonoGame.Extended.Content.Pipeline.dll in the Pipeline Tool. And I used the same version that NuGet … So if you want I can create a project for you but I did nothing special :joy:

P.S. I can start using MonoGame.Extended but not with NuGet :cry:

The interesting thing is that there shouldn’t be any difference between using the NuGet package and building the DLL yourself. Version 3.7.0 of the NuGet packages were only published 4 days ago by the way.

I’m pretty certain that the DLL in the NuGet package is exactly the same as the one that comes out when you build the code yourself. So the problem it seems has to be NuGet or the Pipeline Tool (or the interaction between the two).

So what do we know:

  • Referencing the DLL in the Pipeline Tool via NuGet does not work
  • Referencing the DLL in the Pipeline Tool without NuGet does work.

Does that mean NuGet is doing something weird? Maybe.

What are the possibilities?

  • NuGet puts the DLLs in a different place?
  • There’s a DLL missing in the NuGet package? Unlikely, but possible.
  • The Pipeline Tool isn’t looking in the right place?

I mean, it seems the heart of the problem is that the Pipeline Tool doesn’t support referencing NuGet packages directly. What we’re doing is a workaround at best.

I’ll do some more digging and see if I can figure it out.

Okay. I think I understand the problem fully now.

In short, it boils down to this:

All of the correct DLLs need to be in the right place at the right time.

There’s actually quite a few weird things that can happen so let me explain in more detail.

I’ll start by explaining how I reproduced the problem as closely as possible to your setup.

  • Visual Studio 2017 Community
  • New MonoGame Windows Project template (DirectX)
  • .NET Framework 4.7.2 (must be changed from the default)
  • Installed MonoGame.Extended v3.7.0

Test that MonoGame.Extended is working by drawing a rectangle.

_spriteBatch.Begin();
_spriteBatch.FillRectangle(100, 100, 200, 300, Color.Red);
_spriteBatch.End();

So far so good.

Installing MonoGame.Extended.Content.Pipeline

Next I installed the MonoGame.Extended.Content.Pipeline v3.7.0 NuGet package into the project.

Unfortunately, this is where things start going wrong because it replaces the reference to the MonoGame.Framework.dll with the bait and switch PCL (a complicated topic). Let’s just say that’s not intended behavior and definitely not what we want to happen.

In previous versions of Extended installing the MonoGame.Extended.Content.Pipeline package it would have downloaded the package without modifying the project. You can see in our installation instructions that installing this NuGet package should behave like this:

This package won’t add any references to your project. Instead it will download a DLL that’s intended to be referenced from the MonoGame Content Pipeline tool.

I think this problem came about due to some changes in the way NuGet installs packages that no longer allows this kind of behavior (at least the way we used to do it).

The workaround

The workaround for the above problem (until we’ve got a better solution) is to install the MonoGame.Framework.WindowsDX or MonoGame.Framework.DesktopGL package after installing the MonoGame.Extended.Content.Pipeline package.

This will effectively replace the MonoGame.Framework.dll with the correct one again.

Not out of the woods yet

At this point the project is compiling and running again and we want to start adding the content to our game.

I tried adding a reference to the Content.mgcb file in the Pipeline Tool:

..\..\packages\MonoGame.Extended.Content.Pipeline.3.7.0\lib\netstandard2.0\MonoGame.Extended.Content.Pipeline.dll

In theory, we should but able to build a .tmx file. Unfortunately, this doesn’t work either. We get the Couldn't find a default importer error.

The problem now is that the Pipeline Tool can’t find all of the DLL’s in needs. The rest of the DLL’s aren’t in the same folder as the MonoGame.Extended.Content.Pipeline.dll.

My first thought to workaround this was to change the Pipeline reference to point to the DLL that gets copied to the bin folder at compile time.

/reference:..\bin\Windows\x86\Debug\MonoGame.Extended.Content.Pipeline.dll

This works, breifly, but it creates a new chicken and egg problem.

The chicken and the egg

If we now run “Clean Solution” (to delete the bin folder) the DLL referenced by the Pipeline Tool no longer exists.

MonoGame annoyingly tries to automatically build the Content before recompiling the program. This is a problem because the Pipeline now depends on a DLL that doesn’t exist and the DLL can’t be built because the Content can’t be built.

The ideal solution to this would be to have MonoGame build the Content after compiling the program but there’s no easy way to control that.

For reference, I think this a problem in the MonoGame.Content.Builder.targets file but I’m not sure.

Another workaround.

The simple one.

The simplest workaround to this problem is to put all of the DLL’s somewhere else so they don’t get deleted and reference them from there.

The problem with this “solution” is that those DLL’s are no longer version controlled with NuGet. This of course means that updating your package references could result in a mismatch between versions running in your game and those used to build the Content. Maybe that’s not a huge problem most of the time, but it could get very confusing when it is.

The weird one.

Another quite weird workaround is to add another project to your solution kinda like the old XNA Content projects.

The GameContent project is just a regular Class Library but if you setup your project structure like this:

  • Solution
    • Game (project)
      • References
        • MonoGame.Extended (NuGet package)
        • GameContent (project reference)
      • Content
        • Content.mgcb
    • GameContent (project)
      • References
        • MonoGame.Extended.Content.Pipeline (NuGet package)

Then the compiler is forced to build things in the right order.

It will now make sure that the MonoGame.Extended.Content.Pipeline.dll is copied to the bin folder of the GameContent project before trying to build the Content.mgcb file.

This is truly annoying but it does solve the NuGet versioning problem.

1 Like

Maybe another workaround: include the MonoGame.Extended projects and reference to it. It’s annoying too but it solve mismatch between versions.

Thank you very much for your answers and you time !

Idk if this matters now because I’m kind of late to the party. I’ve found that if I reference the MonoGame.Extended.Content.Pipeline.dll from somewhere outside of the project folder, like in C:/Program Files blah blah, it works. But if I put the .dll in the project folder and the MonoGame pipeline tool resolves the reference with a local path (etc …) Then it doesn’t seem to work. This is with the same exact Dll, built from source.

I hope this is still being monitored:

I have tried different versions of Monogame (3.7.0 & 3.7.1) and visual studie (2017 & 2019).
I have tried with all the combinations the different solutions offered in this topic. However, none of it seems to help.

Is there any progress on what the issue might be and how to fix it?
I tried manually adding all the references.
I tried putting all the libraries in different folders, inside and outside of the project)
I tried with and without NuGet.

I am running out of ideas and was wondering whether someone has achieved a breakthrough?

However: I do get an error code while trying to add the reference to the pipeline in random moments where I cant replicate them. The error code is:

System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.Assembly.GetTypes()
at MonoGame.Tools.Pipeline.PipelineTypes.ResolveAssemblies(IEnumerable`1 assemblyPaths)
at MonoGame.Tools.Pipeline.PipelineTypes.Load(PipelineProject project)
at MonoGame.Tools.Pipeline.PipelineController.ResolveTypes()
at MonoGame.Tools.Pipeline.PipelineController.OnReferencesModified()
at MonoGame.Tools.Pipeline.CellRefs.Edit(PixelLayout control)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at MonoGame.Tools.Pipeline.Program.Main(String[] args)

I hope someone had a breakthrough :slight_smile:

My breakthrough was what I tried in my last comment above. It allowed my content project to build tiled maps.

I just have been rolling with that since it worked for me. Maybe try with a barebone, new/clean project?

I tried the various workarounds listed here and elsewhere, and only really succeeded in breaking things further.

What did work for me was to only install MonoGame.Extended, Tiled, Graphics, and Content.Pipeline, all with the specific version 1.0.617.0.

To get that specific version installed, when I added these packages - by right-clicking “References”, and clicking “Manage NuGet packages”, to get the GUI view (I am not familiar with the CLI commands to get specific versions) - you can then browse for e.g. MonoGame Extended, and on the right panel, instead of keeping the “Latest stable 3.7.0” selected, click the dropdown and install 1.0.617 instead.

Then in my case I had to add a reference to the Content.Pipeline .dll file in my Content.mgcb properties. Once I did that tilemaps were working again.