Is it not possible to share MonoGame code cross-platform?

So after spending far more time than should be reasonable, it appears that there is simply no way to share MonoGame code cross-platform.

Is MonoGame.Portable no longer maintained? There is an out of date pre-release version on Nuget and I couldn’t build it from source because there’s no csproj or build script I could find.

Is no one using using MonoGame to target multiple platforms?

1 Like

The typical approach is to create multiple .csproj files, all linking to the same source files. You then use #if blocks for per-platform code. It’s a bit of a hassle managing the extra projects, but you are definitely sharing your code across multiple platforms.

[EDIT] When adding your source files to a new project, you can use “Add as link” to avoid making a copy.

I believe that MonoGame.Portable is not up to date at the moment.

There is a prerelease of MonoGame.Framework.Portable on Nuget.

Thanks for your reply. That is extremely unfortunate to hear. In addition to being cumbersome, it also requires you to have the source which means shared libraries are out of the question. We have a ban on #ifdefs to prevent this horrible anti-pattern anyway, so even if we could compile everything from source it wouldn’t work.

Right. A pre-release of two versions ago. Hence my question:

Is MonoGame.Portable no longer maintained? There is an out of date pre-release version on Nuget and I couldn’t build it from source because there’s no csproj or build script I could find.

I’ve taken to compiling our shared library against the windows binary and hoping there aren’t any API differences for the other platforms. :frowning:

@nexussays
What are you trying to accomplish? I have a pretty sophisticated project with third party libraries – including SQLite access – and I only had to change about 5 lines of code to get the project to run on OS X and Linux.

My “main” game .exe project is nearly 100% vanilla. I added code to instantiate my game world from a seperate class library assembly and then everything else is loaded from there.

I had to ifdef out my SQLite references / using due to mono using a specialized version of the library.

It’s by no means open the solution, compile, go. However it’s pretty darn close.

And what do you compile that against? That is my dilemma.

If ‘that’ refers to MonoGame it’s the downloaded assembly for each respective platform.

Even though it may not be a best practice I have a separate SLN and CSPROJ for the ‘executable’ project. That way I can focus on keeping any define and platform specific items inside the project as appropriate.

Some folks would recommend adding additional build configurations to your already existing project file – but it can get unruly very quickly if you start targeting a wide variety of endpoints.

I hope to target Windows 10 Universal App, Windows Desktop, OS X, Linux, PS4. I don’t want to have Debug and Release build configurations for each combination inside a single project.

If you want a versatile cross-platform cross-IDE project generation solution – investigate protobuild here. It’s what MonoGame uses to generate their files.

“That” refers to exactly what I quoted :slight_smile:

You said you had a shared class library assembly that contains most of your game code – how do you compile it without a cross-platform reference library?

And I’m not sure who would recommend using the same csproj with completely unrelated build targets – that is horrible advice. Your existing approach is the best one (though I would put them all in the same .sln to minimize breaking changes to the shared lib).

The assembly resolution is handled by the build tools / environment. Since the MonoGame installers take care of this step for us it knows how to resolve the assembly and place it in the output path.

I added code to instantiate my game world from a seperate class library assembly

This is the key thing I still have no answer for. What is this assembly and how is it compiled?

[quote=“James, post:10, topic:2400”]
The assembly resolution is handled by the build tools / environment.
[/quote]Well then I guess my next question is what are those build tools doing? :laughing: Because unless it’s compiling your shared library from source and dynamically referencing a different MonoGame dll for each platform I have no idea how you would compile it.

Just to add some clarification. This is how all of our projects are structured:

  • SharedAppCode.csproj (PCL)
    • References to any ExternalLibrary.dll that are needed (all PCLs or PCL-compatible wrappers we’ve written)
    • 99% of the app/game code
  • Windows.csproj
    • Dependency on SharedAppCode.dll
    • References to any necessary platform-specific versions of libraries in SharedAppCode.dll (eg, ExternalLibrary.Windows.dll)
    • as little code as is needed to instantiate and init the app/game for this platform
  • iOS.csproj
    • same
  • Android.csproj
    • etc…
  • etc…
1 Like

Hey @nexussays

I completely agree. Proper code sharing needs to be at the compiled DLL level so that the source code doesn’t need to be referenced directly. This would make it a lot easier to build libraries for people to use with MonoGame that don’t require a complete re-compile of the MonoGame source code every time the library is referenced from a different platform.

Unfortunately MonoGame doesn’t really work this way. It’s true that there’s a MonoGame PCL project that’s intended to get around these issues but it’s not really a full solution (last I checked).

About a year ago I started working on my own game framework that does share code properly using PCL’s and it doesn’t depend on MonoGame at all. I use it for my own games, but it’s no where near as complete as I would like. I made it open source, and tried to get some people to help but it’s surprisingly difficult to get traction.

These days I’m kinda resigned to the fact that there’s a lot more to making a successful open source project than putting the code online. I’ll keep working on it in my spare time and maybe one day it will become useful to others.

Anyway, I just wanted to put it out there. I built my own game framework to get around this exact problem with MonoGame. It’s probably not a solution to your problem, but hopefully it puts a few things into perspective for you.

The version of the PCL may be behind, however it only needs to be updated when the API interface of MonoGame changes.

However, it will be updated soon following the 3,4 release, just to bring it up to date.

The PCL, doesn’t have any implementation code, just the API landscape, this enables you to code against MonoGame without any platform. When you run it against a platform, it’s that platforms version of MonoGame that is used (a pattern referred to as Bait and Switch)
Platform specific code goes solely on the platform, shared code (in a single project) goes in the PCL project.
You can achieve the same with shared / linked files but usually requires lot’s of #Ifs

If you want to help out, check out the new tool we are using to generate the PCL called Piranah. Still working on the best pattern to deliver the PCL rather than the old way of hand cranking it.

1 Like

As a little update, there is a bit thread about the PCL version of MonoGame on the GitHub site. Lot’s of people getting involved to bring it in to a more automated way of generating it.

Lot’s of work, so little time :smiley:

There’s also plans for a smaller separate “core” pcl to help plugin frameworks such as Farseer and so on, for those projects that only need the math classes and some common code.

1 Like

Is there any documentation / sample code on how to get this working? I spent an hour googling various monogame/portable/PCL/etc. keywords and didn’t find much, either:

  • GitHub issues (which aren’t clear about how this works or if it’s complete)
  • Blog posts from ~2013 mentioning that MonoGame supports PCL now.

@nexussays in your last post, you mentioned a specific project structure. To be clear, that’s the structure you want, which doesn’t currently work with MonoGame, right?

Yes, this is possible to do using Shared Projects…

  1. Create MonoGame projects for each platform you want to target. Delete game1.cs and the content folder from each project.
  2. Create a shared project and put all the game code in there.
  3. Reference the shared project in all the platform projects.
  4. Using the MonoGame Pipeline tool, create a content project, add all your game assets, and save in the “Content” folder of the shared project.
  5. Add the .mgcb file to your shared project.
  6. Hand edit the .projitems file and change the build action of the .mgcb to “MonoGameContentReference”

I’ve got a couple projects on Github that use this technique… here’s a nice simple one:

Hope this helps. Cheers!

1 Like

This is more than what I need. The DesktopGL project seems to be what I want.

Thanks for the example repo, it’s very useful.