MonoGame – Building multi-platform solutions

Sept. 19, 2016
protect

To accompany the video project for the walkthrough of building multi-platform solutions with MonoGame, this blog post will walk you through some best practices and tips and tricks for starting and managing your MonoGame projects, with the aim to take them to as many platforms as possible with the least amount of pain.

The video for this post can be found here if you prefer video:

<iframe title="Monogame - Building multi-platform solutions" src="//www.youtube.com/embed/WonVmlpPBuU?enablejsapi=1&amp;origin=https%3A%2F%2Fwww.gamedeveloper.com" height="360px" width="100%" data-testid="iframe" loading="lazy" scrolling="auto" class="optanon-category-C0004 ot-vscat-C0004 " data-gtm-yt-inspected-91172384_163="true" id="223741216" data-gtm-yt-inspected-91172384_165="true" data-gtm-yt-inspected-113="true"></iframe>
This and more content can be found on my dedicated MonoGame channel here: http://bit.ly/darksideofmonogame

Days gone by with XNA

As with most posts in my MonoGame series, I like to give a brief overview of what happened in XNA days, mostly to show you how MonoGame has evolved but also to help you if you are upgrading old XNA projects.

XNA Game Studio didn’t really have a multi-platform strategy as such, sure you were able target multiple platforms but nothing like what we have today with UWP and Xamarin.  There was some sharing going on, mainly surrounding the Content Projects.  Code wise however, the only sharing that was really considered, was being able to build reusable code for the same platform. To share code between different platforms you had to resort to some basic coding practices in order to make things happy.

 

Sharing Content

As you can see here, sharing content was easy enough between any platform.  You just had to be sensible about what content you shared paying careful attention to resolution, size and so on:

image

image

Xbox and Windows Project using the same Content Project

Sharing Code

XNA provided you with special Game Library projects to allow you to store code outside of your project, similar to normal C#/VB Library Projects.  If you tried normal library projects they would only work on Windows and not on Xbox or Phone.  The drawback with these specific class libraries was that you could only use them on the platform you created them for, so they couldn’t be used by any other platform:

image

image

Libraries only compatible with projects for the same platform

These worked well if you build say a Sprite Animation system or a good save game library for a platform that you wanted to reuse for all your games, but no good if you wanted to use it elsewhere.

This left you with the traditional options to use the same code:

  1. Copy / Duplicate the code
    Not very practical, double the effort and a nightmare to debug.

  2. Reuse the code from another platform
    Worked but created problems when you needed to manage platform differences, messy code.

  3. Create multiple library projects and link the code
    This was a practical option but meant more management and control over the library code.

  4. Store shared code in another project / folder and link the files
    Best practice but needed a firm hand.  Had to share / link the code since there were no libraries able to cross platforms. All code kept within the project.

Everyone I know from those days used what worked for them, everyone had their own preferences. Personally I used a combination of 3 & 4 depending on what was being shared.  Specific libraries were kept separate in their own projects and true game code always stayed in the project.

 

Nowadays we have more tools to hand to make the job easier, which I’ll highlight with MonoGame

Building the future

With MonoGame, a lot of the above still applies, but I’ll walk-through some of the best practices with a few tips and tricks on how to make the best of it.

Others will still have different ideas, so I encourage anyone to comment below if they have some other ways of working. What follows is what I use as a rule of thumb with all my own projects.

Sharing Content

image

image

Sharing Content Projects are quick and easy. Multiple Content Projects per-platform are supported.

Not much has changed regarding sharing content, no point in breaking what was already a good solution.  Content is managed separately, has its own projects and more importantly, they are no boundaries.  If anything, the MonoGame content project system is a further evolution on the content system:

  • Content Project definitions are text based
    The XNA system was good but you had to work with all of MSBuilds way of managing a csproj file.  It worked but there was a lot of overhead.  MonoGame’s Content Project definition files are much simpler and they use a cut down XSD schema focusing on just the content and what it is. Plus (if you wish) you can easily generate them on the fly (if you build your own packaging system).
    In a lot of ways, they were made to be human readable so you can either use the MGCB tool to manage them, or just open your test editor and hack away, your choice.

  • Their platform is determined when you build the project
    You can either fix the platform build type (which is like setting a default) and build the content manually (you can also call the MGCB tool programmatically from a build script to build it separately if you wish as well, for advanced users). Alternatively, if you have your content file attached to your solution (which is the default), then Visual Studio will tell the Content Project which platform to build based on the platform you are building automatically, regardless of whether you share the project or not.  This means you don’t have to worry if the content will work on the platform or not (as different platforms use different methods for compression, formatting and so on. An XNB file built for Windows likely won’t work on Android for example.

  • They are extensible
    Like its XNA predecessor, MonoGame has the same Content Pipeline Extension capabilities and can support building your own methods for interrogating (importing) and processing (exporting) asset files.  This is extremely useful when you want to manipulate the asset or get more data out in multiple structures that your game can use. Say extracting Normal and Tangent data from a model for lighting calculations, or using the colors of an image to generate a heightmap. (more posts in the future on this)

Sharing Code

Out of the box sharing code between platforms has not changed much, although MonoGame can now benefit from more modern standards for sharing code if you wish (with a little work).  What follows are my personal best practices when starting any project which you intend to deploy across multiple platforms, even if you only start with one, if you follow these simple steps you will save yourself a ton of rework later when you want to add more.

Some considerations you should keep in mind (will go in to more detail later):

  1. Where possible, write core game code within a single solution (except plugin’s and libraries).  Keeping everything about the game in one place, such as: Data structures, logic, movement, workflows and state management.  This will make sharing the core of the game a lot easier.

  2. Use a Game specific namespace for all your core game code. Keep it separate from any platform, ideally it should be platform agnostic.

JikGuard.com, a high-tech security service provider focusing on game protection and anti-cheat, is committed to helping game companies solve the problem of cheats and hacks, and providing deeply integrated encryption protection solutions for games.

Read More>>