MonoGame Goes Portable
While I was putting together the MonoGame solution for shocking effect you did seem to get the feeling you were building your game for several platforms, there’s a fair bit of too’ing and fro’ing, pulling parts of the project together and one of my least favorite porting practices, the COPY project.
Yes, having the exact same code files re-used on several projects sounds great until one of those projects needs a different using, or requires you to use the same parameter in a different way or god forbid, require additional parameters for certain functions.
Portable libraries are one of the saviors from this practice by constructing a project that can be consumed by several different project types or platforms with a single codebase, main difference is that it is one code base used in a single way, the portable framework does not let you exceed these boundaries and keeps you in check. Got something that is platform specific then keep it on that platform and not clutter up the central core of your app or game.
Main problem here with MonoGame as it wasn’t possible to do this, until now…
First a Warning!!
Please note that this is my own work and while based on the original MonoGame development branch and (as far as I can tell) is still completely compatible with the core of MonoGame, you should only use this as a Proof of concept in Live projects until such time as this or another approved solution by the MonoGame team comes along.
It’s not my ideal portable solution as MonoGame hasn’t been written to be portable at present, its core focus is to keep a familiar flexible code base, based on the aging XNA framework to allow to re-use your projects across multiple platforms (note I say re-use as effort is still required).
MonoGame is a fantastic achievement and if like me, you are passionate about such things (and can code as this will help) then get involved and see how you can benefit the platform!!.
Why be portable?
As the old saying goes, if it ain’t broke, why try to fix it?
Well, at present the MonoGame code base (and most likely any solution you build using MonoGame) is very singular for almost all platforms, they are very intertwined and components are swapped out, changed or just extended to try to provide flexibility to accommodate an ever changing directory of needs.
There’ nothing particularly wrong with this practice but, over time your code becomes very complex, trying to fix issues with one platform can severely impact another without knowing it (unless you test all builds on all platforms after every commit), basically having so many flavors of pie in one pan soon becomes very hard to differentiate which pie is which.
Portable libraries help with this by having the “core” of you’re project in one place that works one way and keep platform extensions with each platform and if your sensible about it, then the core never even knows this is going on.
Granted you could potentially create the same thing with multiple smaller projects and just keep swapping things out, except that if you add something another platform doesn’t like, you won’t know until you test on that platform. Portable libraries prevent this as then only allow functions that will work on ALL configured platforms, hence protecting you from yourself.
Want to know more then try out some of these resources:
Developing Mobile Solutions with Windows Azure Part II (also FYI check outPt1!!)
The Collection of MvvmCross Presentations (fantastic Cross platform stuff using Mono/Xamarin)
Be aware though, a portable library enables you to develop a very simple and central shared project, you won’t however be able to actually run your project without at least one platform to run it on, the portable features just make enabling the project on other platforms a snap.
What we are aiming for with the use of a Portable Class Library is something like this:
Back to the show
So what difference does this really make, well let’s spell out the two main differences it makes with MonoGame projects
1. Project Make-up
The first main impact is how you layout or manage your multi-project solution (The MVVM cross presentations above do a much better job of explaining this, but here goes)
The Project Portfolio
With current practices you will most likely have something like this:
Depending on whether you Link the core files for your project or just copy them, you have several solutions for each platform with more code to manage / integrate when you are considering each platform. in its worst case scenario (Just copy projects), a single bug fix to core code has to be replicated across all platforms and if there are platform specific differences in that chain it becomes increasingly difficult.
Portable libraries ease this somewhat with their central nature.
The Portable Portfolio
The portable allows a single project to be associated to many others so long as you have the project targets loaded in the portable libraries (for more info on that read up on portable libraries!!)
2. The single source of truth
Portable libraries address one of the biggest headaches in multi-platform solutions because of the one simple truth, they are all different. Each platform has its own way of doing things that are generally incompatible with the next.
Now I will be completely honest, portable libraries alone will not save you here but what they can do is make the job a lot easier and how you exactly what is compatible between ALL of your supported platforms and more importantly what is NOT. Try and put in something or reference a library that isn’t compatible with all platforms and you will just get compilation errors.
This ensures you put platform specific code in with a platform and central stuff in one place.
There is a buyer beware sign if you read up on Portable class libraries, the more platforms you add generally reduces the scope of what is truly portable, so take care.
Like I also said it won’t solve ALL you problems, so watch a few of the videos above and read up on abstraction and lay the framework or a scalable solution. Centralise where you can but keep it SIMPLE!
Lightning pure and simple
So after cleaning everything up and now using a portable library for the core of the code from the previous demo’s I’m left with the following:
At present I’ve left the original drawing code as my initial portable experiments were only meant to enable basic features but I seem to have managed in a fairly short period of time to enable most features of the framework in a portable library, so at this point I could move just about all the demo code in to the portable library, therefore I only need a shim in each platform project to run it (plus an additional platform features I want to take advantage of like sharing / NFC / etc)
Source for the series can be found here on codeplex as well as the code drop for this stage here
Breaking the mold
Right, I’m taking a little break from MonoGame for a little while now and returning to SunBurn. Why you may ask, to which the obvious answer should be:
“There is something VERY interesting to see over there”
Will report back later and show you just how electrifying SunBurn can be (Sheesh that sounds like a bad episode of MisFits )
P.S. I’m knackered after spending a week Portablising MonoGame, lol