Porting your Windows XNA game to MacOS using MonoGame and MonoMac Part 1

Edit May 25, 2012 – Start

A LOT has changed since I first wrote this guide. The versions of MonoGame, MonoDevelop and Mono Framework are different enough now to cause some confusion when reading this guide. I don’t have the time to do a full re-write especially considering that things are going to continue to keep changing, but if you encounter a problem please do not hesitate to post your question in the comments section. I will do my best to help out. You can also check out the existing comments to find solutions to some discrepancies or just visit the MonoGame and MonoMac forums. Thanks!

Edit May 25, 2012 – End


Introduction

This guide has a total of 4 parts. If you have a 2D Windows XNA game or engine that you would like to port over to MacOS, you should strongly consider using the MonoGame and MonoMac frameworks. Before I found out about MonoGame and MonoMac, I started porting from scratch using Objective C and Cocoa and it was a disaster. Perhaps it might have been much easier for someone familiar with Objective C and Cocoa, but for someone like me who had no experience whatsoever with the language or the API it was…sad…to say the least. Probably would’ve taken me months had I followed through. And even if I was an Objective C and Cocoa master I’m still guessing it would’ve taken about a month of work. That’s when MonoGame and MonoMac swooped in to save the day and I had my game running 99% correctly in just a few hours. This will be a guide to get that 99% going for you and also hopefully finishing out that final 1%. Thanks to Dominique (CarteBlanche) for adding video to the project and super dooper special thanks to Kenneth (kjpou1) for fixing all the issues I found when I started with MonoGame. If it wasn’t for him this guide would be 10 times longer! Ok, let’s get started!



Make sure your Windows XNA game will be compatible with MonoGame

The current version of MonoGame (2.0) doesn’t officially support 3D but there are cases of people modifying some libraries and getting 3D to work. I don’t cover any 3D in this guide, so if your game has 3D it’s really going to be up to you to figure it out.

You will not be able to use audio with XACT. A very simple alternative is using SoundEffect SoundEffectInstance classes. It is incredibly easy to modify your Windows XACT code to use SoundEffect SoundEffectInstance, HOWEVER, I personally have had problems getting SoundEffect/SoundEffectInstance to work correctly under Windows XP where as XACT works just fine. So I decided to leave XACT on my Windows game and just use SoundEffect/SoundEffectInstance on Mac. But again if XACT is critical to you then you should read next section and experiment with some samples before proceeding.

The original project on Windows must be compiled with XNA 4.0 or higher

It should be using the Reach Profile not the HiDef profile

If your game has video, please be aware that MonoGame for now only accepts the following video file types: mp4, mov, avi, m4v, 3gp. If you can’t convert your video to one of these types, MonoGame will not be able to load it. Video in MonoGame also takes a lot of work to get high functionality from so perhaps you’ll want to try out the Monogame Video sample which I go into in the next section. Lets start by downloading all the necessary tools on your Mac.


Download the complete XCode developer toolset for Mac, iPhone and iPad.

-The best place to get it is from
https://developer.apple.com/downloads/index.action

*In the downloads search bar, all the way on the left, type in XCode, then download the .dmg file for the latest version of XCode toolset which at this time is XCode 4.1 for Lion (3.1 gigs) and XCode 4.1 for Snow Leopard (4.6 gigs). This will ensure you have all the tools necessary, like Icon Composer and PackageMaker, to complete your project.

*Double click the .dmg file once it’s been downloaded and install with all default settings.


Download MonoDevelop

*Go to http://monodevelop.com/

*From main page click on Download button->Choose MacOSX

*At the time of this writing the latest stable version is MonoDevelop 2.8.2 so download that package (.dmg file) and if you see any other required packages, which as of right now is Mono 2.10.5 + GTK#, click on the download link, you will be taken to a new page.

*1. “Select Platform:” MacOSX

*2. “Download Mono for MacOSX:” Click on the SDK link and download that .dmg file


Install MonoFramework

-Install the MonoFramework by double clicking on the .dmg file which right now is
MonoFramework-MDK-2.10.6_1.macos10.xamarin.x86.dmg

*This launches installer, leave all default values, keep hitting Continue button then finally Install button, close when done.


Install MonoDevelop

-Install MonoDevelop by double clicking its .dmg file which right now is MonoDevelop-2.8.2.dmg

*Drag MonoDevelop icon into applications. Hit replace if upgrading from an older version. Wait till it’s finished processing then close that window.


Install MonoMac plug in

-Install the MonoMac plug in, by running MonoDevelop from Applications

*MonoDevelop Menu Item->Add-In Manager->Gallery Tab

*Make sure “All Repositories” is selected

*Expand “Mac Development”

*Highlight “MonoMac Development”

*Hit “Install”

*When it’s installed, restart MonoDevelop

*To confirm that it’s installed go to File->New->Solution->C#->MonoMac and you should see 3 MonoMac templates

*Close MonoDevelop


Download MonoGame framework

-Download the MonoGame framework that you will eventually add to your project:

*Go to https://github.com/mono/MonoGame

*All the way on the right it says “Current Branch:” make sure it says “Develop”, there is a dropdown box that should allow you to choose that. This is the most up to date version and as of this writing contains a lot of the framework fixes that I partially helped debug.

*There is a “Zip” button near the top, click on this and download it and unzip it

*You should rename the unzipped folder “MonoGameFramework” for easier reference in this guide.


Getting the samples

That’s all you need to port your game. But I STRONGLY suggest you also download MonoGame and MonoMac samples as they will come in handy when trying to figure things out.

MonoMac samples can be found here https://github.com/mono/monomac/archives/master just click the “Download zip” button near the top.

MonoGame samples can be found here: https://github.com/CartBlanche/MonoGame-Samples just click on the “Zip” button near the top. You should rename the unzipped folder “MonoGameSamples” for easier reference in this guide.

Once unzipped the MonoMac samples are pretty simple to run, just double click on the .sln files, MonoDevelop should open up, then just go to Run->Debug and the sample should start running. Not all of them work though, but most do.


Getting MonoGame samples to work

The MonoGame samples take a bit more work to get going. This is what you do:

*Go to MonoGameSamples\Samples and double click on the MonoGame.Samples.MacOS.sln file.

*MonoDevelop should launch and you will immediately get a notification that 2 projects could not be found. This is fine, just hit OK.

*If you can’t see the Solution Explorer on the left, go to View->Debug and it should appear.

*If you expand the solution you will see “load failed” errors next to Lidgren.Network.MacOS and MonoGame.Framework.MacOS.

*Right click on each one (just those 2 projects) and hit Delete->Remove->Ok

*Right click on the listing for the Solution all the way at the top of the Solution Explorer and hit Add->Add Existing Project… If you renamed your unzipped framework to MonoGameFramework as I suggested, then navigate to MonoGameFramework\ThirdParty\Lidgren.Network\Lidgren.Network.MacOS.csproj file and hit Open->Ok

*Do the same as above but add the MonoGameFramework\MonoGame.Framework\MonoGame.Framework.MacOS.csproj file and hit Open.

These 2 projects are ALWAYS necessary in any MonoGame solution. And always make sure that the MonoGame.Framework.MacOS project always has a reference to the Lidgren.Network.MacOS project. To do this expand MonoGame.Framework.MacOS project in Solution Explorer. Expand “References” and you should see it listed there. If not, right click on “References” folder Edit References->Projects Tab->Check Lidgren.Network.MacOS->Ok

And you also have to make sure that any of these sample projects have at least a reference to MonoGame.Framework.MacOS, sometimes they require both. A simple project that should work right off the bat would be PerPixelCollisionSample. It should be referencing MonoGame.Framework.MacOS. If not add the reference.

Right click on PerPixelCollisionSample and select “Debug item” and it should just run. Most other samples should run fine as well just always check to make sure all references are correct.


A few words regarding video

If your game has video you should definitely try out the Video sample and see if you feel comfortable with it. (btw, the current video sample opens up in full screen which makes you have to force quit the program to close it. To fix this, in the Game1 constructor change graphics.IsFullScreen = true; to false and it will work right ). If MonoGame’s implementation of video is just what you need then great! But if not, you may have to put a bit of work into it. Video, by far, took me the most amount of effort to get it to work the way I wanted. In Solution Explorer, if you go to MonoGame.Framework.MacOS\MacOS\Media\Video.cs file you will see near the top:

private QTMovie mMovie;
private QTMovieView mMovieView;

So as you can see MonoGame basically used MonoMac’s implementation of QTMovie and QTMovieView. I created my own QTMovie and QTMovie view objects and bypassed MonoGame’s implementation altogether to get the functionality I required. You can research these classes fully at developer.apple.com. Because MonoMac is so awesome you can basically do anything with it that you can do with Cocoa so any documentation you read on developer.apple.com will for the most part apply to MonoMac’s implementation of it as well. Sometimes the method names are a bit different but it’s all basically there. Don’t worry you won’t need to learn OpenGL or anything like that. Just study the documentation and study MonoGame’s implementation of Video and VideoPlayer and I’m sure you’ll be able to work it out.



This concludes Part 1 of the guide. In Part 2 I will begin to detail how to create the MonoDevelop project that you will use to port over your game.

23 thoughts on “Porting your Windows XNA game to MacOS using MonoGame and MonoMac Part 1

  1. Pingback: The Great Porting Adventure: Day 3 « Ben Kane

  2. Cool logo.The coolest thing begin that Mono is ivling and is becoming richer every day !(as MS does not want to bring Silverlight to Android, and as Android is becoming the biggest platform, we are numerous to bet on Mono to help us going on with .NET. Not a lot of C# programmer are wanting to come back 20 years in the past and reuse eclipse and java !).

    • Thanks. I couldn’t agree more. I have a free demo for a game coming to iOS and MacOS in the next few weeks, but then immediately I’ll be diving into the Android port. Pretty exciting stuff!

    • Fixed. MonoMac didn’t have OpenAL integrated until 3 months ago. Naturally, Unity’s MonoDevelop fork does not have that version of MonoMac yet, so it didn’t work. I just downloaded MonoDevelop off their website as a separate version, and it worked.

      • Cool man. I’m glad it worked for you. I wrote this awhile back so I know a bit has changed. I checked out Bedroom Racer, it looks really cool! I’m dying to get into 3d graphics myself, but I got so much on my plate right now. Anyway, good luck with your game and projects!

  3. hey guys, i followed this tutorial, but at the end I ‘ve got some errors in the GameWindow.cs class go MonoGmae.Framework.MacOS:

    /Users/Crybot/Downloads/MonoGame-2.5.0.0/MonoGame.Framework/MacOS/GameWindow.cs(33,33): Error CS0103: The name `AddCursorRectcursor’ does not exist in the current context (CS0103) (MonoGame.Framework.MacOS)

    can someone help me please?

    sorry for my english, i’m italian ;)

    • Hi! The same thing happened to me! I think it might be something with the newest version of MonoFramework. Anyway, just go into the framework and change “AddCursorRectcursor” to “AddCursorRect” and that should solve the problem. At least it did for me. Let me know how it goes.

  4. Hi again…
    Can someone tell me how to insert sprite fonts into my game? I’m getting runtime error when I try to load them…

    thanks ;)

    • Hi. I got it to work by adding the .xnb file to the project instead of the .spritefont file. You can find all your xnb files in the debug or release folders of your original windows project. Let me know if that works.

  5. Hi when i Try to build the monogmae samples I keep getting the error “The type or namespace name `Xna’ does not exist in the namespace `Microsoft’. Are you missing an assembly reference? (CS0234) (MonoGame.Samples.Aiming.iOS) ” What am I doing wrong ? Or what did I miss ? Can’t get any project with reference to microsoft.xna.framework.* to work. Please help !

    • Hi. Are you adding the MonoGame.Framework.MacOS.csproj project to your solution? If so, are you making sure to add a reference to that project in your game project by right clicking on “References” folder Edit References->Projects Tab?

  6. Hi. Thanks for the guide, it’s great. However I got the following error when I try to build the project (PerPixelCollisionSample).

    Build Successful. The given key was not present in the dictionary.

    Anyone can help me please? Thanks

    • Hi I just downloaded the newest version of MonoGame and the newest version of the MonoGame samples and the PerPixelCollisionSample failed when I first built it because of the AddCursorRectcursor error that i mention in another comment, but after fixing that, the sample ran fine. Are you using the latest version version of MonoGame and the MonoGame samples? Also make sure you have the latest version of MonoDevelop as well. If you already had the latest versions of all the above, then did you try going to Run->Start Debugging ? What happens when you try that? Let me know.

      • Hi and thanks for your answer.

        I’m using MonoDevelop 3.0 and MonoGame 2.5.0

        I renamed the AddCursorRectcursor function and here’s my building output.

        Thank for your help.

        Building Solution: MonoGame.Samples.MacOS (Debug)

        Construction : MonoGame.Samples.BouncingBox.MacOS (Debug)
        Performing main compilation…
        /Library/Frameworks/Mono.framework/Versions/2.10.9/bin/dmcs /noconfig “/out:/Users/Davidson/Downloads/CartBlanche-MonoGame-Samples-3548043/BouncingBox/bin/Debug/Microsoft.Xna.Samples.BouncingBox.MacOS.exe” “/r:/Library/Frameworks/Mono.framework/Versions/2.10.9/lib/mono/4.0/System.dll” “/r:/Library/Frameworks/Mono.framework/Versions/2.10.9/lib/mono/4.0/System.Xml.dll” “/r:/Library/Frameworks/Mono.framework/Versions/2.10.9/lib/mono/4.0/System.Core.dll” “/r:/Library/Frameworks/Mono.framework/Versions/2.10.9/lib/mono/4.0/System.Xml.Linq.dll” “/r:/Library/Frameworks/Mono.framework/Versions/2.10.9/lib/mono/4.0/System.Drawing.dll” “/r:/Applications/MonoDevelop.app/Contents/MacOS/lib/monodevelop/AddIns/MonoDevelop.MonoMac/MonoMac.dll” “/r:/Users/Davidson/Downloads/MonoGame-2.5.0.0/MonoGame.Framework/bin/Debug/MonoGame.Framework.MacOS.dll” /nologo /warn:4 /debug:full /optimize- /codepage:utf8 “/define:DEBUG;MONOMAC” /t:exe “/Users/Davidson/Downloads/CartBlanche-MonoGame-Samples-3548043/BouncingBox/FPSCounterComponent.cs” “/Users/Davidson/Downloads/CartBlanche-MonoGame-Samples-3548043/BouncingBox/main.cs” “/Users/Davidson/Downloads/CartBlanche-MonoGame-Samples-3548043/BouncingBox/Game1.cs”

        Copying content files
        Copying ‘/Users/Davidson/Downloads/CartBlanche-MonoGame-Samples-3548043/BouncingBox/bin/Debug/Microsoft.Xna.Samples.BouncingBox.MacOS.exe’ to ‘/Users/Davidson/Downloads/CartBlanche-MonoGame-Samples-3548043/BouncingBox/bin/Debug/Microsoft.Xna.Samples.BouncingBox.MacOS.app/Contents/MonoBundle/Microsoft.Xna.Samples.BouncingBox.MacOS.exe’
        Copying ‘/Users/Davidson/Downloads/CartBlanche-MonoGame-Samples-3548043/BouncingBox/bin/Debug/Microsoft.Xna.Samples.BouncingBox.MacOS.exe.mdb’ to ‘/Users/Davidson/Downloads/CartBlanche-MonoGame-Samples-3548043/BouncingBox/bin/Debug/Microsoft.Xna.Samples.BouncingBox.MacOS.app/Contents/MonoBundle/Microsoft.Xna.Samples.BouncingBox.MacOS.exe.mdb’
        Build complete — 0 error, 0 warning

        Updating application manifest

        ———————- Done ———————-

        Build successful.
        Build failed. The given key was not present in the dictionary.

        • That is a very odd bug. I’ve never seen that before. I really have no clue whats causing that kind of build output. I researched it a bit and found all different kinds of suggestions. Just google: “The given key was not present in the dictionary” AND “MonoDevelop” and you should find some info. It might have to do with the order that you installed everything. Perhaps you installed MD before the MonoMac framework?

          • Hi,

            I tried several stuff to fix my issue but no success. It seems that the issue arises from info.plist but I need to look deeper before asserting that.

            In the meantime, I installed an older version of MonoDevelop along with older packages for MonoGame and MonoMac. All seems to be working now.

            Thanks for your time and your awesome tutorial.

            Cheers,

            Arcanes.

          • Cool. Glad it’s working out. And thanks I really appreciate your kind words about the guide. Btw, I added an “Edit” section to Part 4 of this guide. It briefly covers some steps needed to actually submit the game to the app store that should save people some time. Good luck! :)

  7. Hi,
    Excellent tutorial. Thanks.
    In the 2nd part you mention you have to create an Empty Interface Definition called “MainMenu”. For me, at least, it refused to run until I re-named that file “MainWindow”. Hopefully that will be of use to someone.

    Currently I do have problems with IsolatedStorageFile though, namely getting an exception thrown whenever I try and use it:
    “No ApplicationIdentity available for AppDomain”

    If anyone has any suggestions that would be much appreciated!

    • Hey thanks. I updated that section and said to try “MainWindow” if “MainMenu” doesn’t work. As for IsolatedStorage, not sure how far their implementation of it goes. But I allow for saving in my game and I just simply used the XmlSerializer. Something like this:

      using System.IO;
      using System.Xml.Serialization;

      [Serializable]
      public struct SaveGameData
      {
      public String sData1, sData1, sData3;
      }

      SaveGameData sgdDataToWriteToFile, sgdDataReadFromFile;

      //To save to file
      sgdDataToWriteToFile.sData1 = “Data1″;
      sgdDataToWriteToFile.sData2 = “Data2″;
      sgdDataToWriteToFile.sData3 = “Data3″;

      FileStream stream = File.Open(“MySaveFile.sav”, FileMode.Create);
      XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData));
      serializer.Serialize(stream, sgdDataToWriteToFile);
      stream.Close();

      //To read from file
      FileStream stream = File.Open(“MySaveFile.sav”, FileMode.OpenOrCreate, FileAccess.Read);
      XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData));
      sgdDataReadFromFile = (SaveGameData)serializer.Deserialize(stream);
      stream.Close();

      String sValueRead1 = sgdDataReadFromFile.sData1;
      String sValueRead2 = sgdDataReadFromFile.sData2;
      String sValueRead3 = sgdDataReadFromFile.sData3;

      Hope that helps.

      • Hi.

        Thanks, I’ve managed to fix that. I’m actually converting a W7Phone XNA project, so while 99% is the same you’ll still get the occasional thing you need to change.

        It still crashes, but all the examples (e.g. The perpixelcollision sample) crash at the same point(when mono to render a scene get_CGLContext() ) so I’ve either configured it wrongly or happened to download the framework when it was not working properly.

        I’ll keep at it! Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>