Chris Risner . Com

MonoGame xPlat Starter Project

Posted on: 10/24/2014 3:51:00 PM by

TLDR: You can access the source code here.

Sometimes one of the hardest things to do is just get started with something.  Over the past couple of years, I’ve taken a few cracks at getting back into game development mostly by looking at xPlat frameworks such as libGDX and MonoGame.  One of the really nice things that libGDX has is a Setup Project app that, when ran, generates projects for the different platforms that the framework works on as well as a single place for shared code and the place to put all of your shared resources.  This makes it super easy to get started and running your app on all of these platforms (Android, iOS, Windows, OS X, etc).  Unfortunately, MonoGame doesn’t have a similar feature.  Every time I’ve gotten back into MonoGame this has affected me because when I start development with a cross-platform framework, one of the first things I like to do is make sure things are running on all the platforms I intend to target.  With any framework, I think you will probably end up finding things that you need to modify for specific platforms but it’s nice to see a very simple app (I won’t call it a game at this point) running cross-platform.

In order to make it easier on other people who may be trying to tackle the same issue, I spent the time getting the same app running on Android, iOS, and Windows Phone (the three platforms I’m interested in targeting right now).  There are several reasons today why this is complicated:

  • Version 3.2 of MonoGame (including project templates) has been released for Windows and Visual Studio, but NOT for other platforms (OS X being the one I need).
    • There are NuGet binaries you can use but that’s not without it’s own issues.
    • The other option, which I used, was to compile the source code from GitHub.
  • The Content Pipeline tool isn’t part of the public build yet (or at least it doesn’t seem to be) requiring you to grab the source for MonoGame and compile it.  The Pipeline tool is really important if you want to compile your resources into the optimal format for each platform (recommended) and prior to the MonoGame folks making a tool, you had to use the old XNA Content project stuff (nightmare if you don’t already have a machine set up with it).
    • For more on the Content Pipeline tool, check out this video from Xamarin Evolve.
    • Since this isn’t in the public build, I had to compile it from source too.
  • There are two different ways to share code (i.e. put all your game code in one place) with MonoGame (and Xamarin):  PCLs and Shared Projects.  They both have their pros and cons but I decided to use Shared Projects.  This allows you to create code which is compiled for whatever platform you’re currently building for and you can do #if to put platform specific code.  While the shared project type is supported by VS 2013 Update 2, you can’t actually add a reference to a shared code project (at least not a Windows Phone one).  To get around this there is Visual Studio Extension called the Shared Project Reference Manager that you just install and you’re ready to go.

It might seem like the first two bullet points are bashing the folks who work on MonoGame but that’s far from how I feel.  MonoGame is a free framework and the people that work on it seem to do it on a volunteer basis.  I have nothing but respect for these people and think they’re doing a great job.  I, like everyone else wish they could do it faster / become rich for their efforts / make everything work just as easily on OS X, but in the meantime, I’ll do what I can to bridge some gaps. 

The Source Code

The code for the starter proejct is available on GitHub and comprises the following:

  • Solutions for Xamarin Studio (with iOS and Android projects) and Visual Studio (for Windows Phone)
  • A Shared Project with the Game class in it
  • iOS, Android, and Windows Phone 8.1 projects which all reference the Shared Project and use it’s Game class
    • The Android project is targeting 4.2
    • You might need the above mentioned Shared Project Reference Manager for the WP project to compile.
  • A local libs folder that contains iOS and Android MonoGame framework assemblies built off the Dev branch
  • The Windows Phone project is referencing the DLLs for MonoGame installed with the VS 2013 installer for MonoGame
  • Assets for each platform (only the Windows Phone version is compiled into an XNB for now)

Running the app currently works on each of these platforms and shows the MonoGame logo.  This is laughably far from being a game you could run or do anything with but it’s a good template for starting out.  Hopefully this provides a jumping point for other people to work on cross-plat games.

Categories: Games, MonoGame, Xamarin
Bookmark and Share
First Article

Getting SignalR to Work with Azure and Orleans

Posted on: 10/23/2014 9:18:00 PM by

SignalRI just recently posted the source code and link to the Adventure style game I built with Orleans and Azure.  Today I’d like to talk briefly about how I got SignalR to work.  If you haven’t looked at SignalR before, it’s a very cool library which makes it easy to add real-time functionality to your applications.  In more simple terms, it makes it possible for you to push information from your server to the client instead of having to ask for updates.  This is really powerful because you can deliver instant updates to the client when a change happens on the server. 

To add SignalR to my sample, I worked off of the GPSTracker sample provided with Orleans.  One issue I had to figure out that the GPS Tracker doesn’t cover is getting things to work on Azure.  As it turns out (and I’ll provide more detail below) there weren’t any big changes just because we were on Azure, however, figuring out how to open the path from Worker Roles to Web Roles for SignalR was something I had deal with.

SignalR in AdventureTerre

For AdventureTerre, there were a few different scenarios I thought SignalR might be useful.  If you go play the game right now, I didn’t leave any of them in but turning them on is easy.  The first scenario and the one I implemented was having monsters (as well as NPCs) have the ability to move between rooms.  The way this works is that, if specified that they should be able to move, an Orleans timer is created on the grain telling it to attempt to move very couple of minutes.  The timer causes a method on the Monster / NPC grain to fire which will randomly choose a direction and then, if there is a room in that direction, will move the monster / NPC.  When this happens a message is sent to any players in the old room letting them know the character left the room and a different message is sent to any players in the new room letting them know the character has entered the room.  Pretty simple but a much better experience than looking at a room one second and not seeing a monster there and looking again a second later and seeing one there.  There were other possible scenarios I thought of including having the monsters / NPCs randomly say something to players in the room as well as having players say things to one another (right now the game is strictly single player). 

SignalR and the Web Layer (Web Roles)

Getting SignalR to work with Orleans requires a little more thought due to how SignalR and Grains work.  When a client (our website) opens, we use JavaScript to connect to a Hub running in our web application.  Upon connecting to the Hub, the hub adds the client’s connection to a group based off of a cookie value (which is also tied to the player).  These groups are how messages are later sent.  Essentially the hub is told “send this data to this recipient” and the hub does that based off the group they’re in.  (since the cookie is tied to the player, when we want to deliver a message to the player, we tell the hub to deliver to the group also tied to the cookie value)  let’s take a look at some of the code for this.  First the JavaScript in our website:

This is pretty straight forward.  We create a hub tied to a PlayerHub and start it which connects it to the Hub on the server.  We also define the methods playerUpdate and playerUpdates.  Now let’s look at the PlayerHub which is a Controller in the web app:

Here again we see the update methods though we specify who the message should be sent to (the Recipient field is the cookie value mentioned above).  The OnConnected method makes sure it’s not a Grain connecting to the hub, and if it isn’t, adds the connection to a Group based off the cookie value.  From the web app side, that’s all we need to do (you also need to reference the SignalR JS libraries and the SignalR NuGet where appropriate but I’ll leave that up to you).

SignalR and the Orleans Silo Layer (Worker Roles)

If we were just triggering pushes to our client when something happened in our Web Roles, we wouldn’t need to worry about anything else.  However, our Grains and Silos are running in Worker Roles.  Those Worker Roles don’t have any concept of our hubs or the connections they have to our clients.  In order to deal with this, we add a PushNotifierGrain which handles talking from our Silos back to our Web Roles.  Let’s first look at the interface, IPushNotifierGrain:

The important method here is the on that sends a message to a recipient.  Let’s look at the implementation:

There’s a lot going on here but it’s all pretty easy to understand.  The private vars hubs and messageQueue keep track of our hub references and a queue of messages to deliver respectively.  ActivateAsync creates a timer to regularly flush (send out) messages, refresh our hubs, and creates a timer to refresh the hubs every once in a while.  RefreshHubs goes through every instance and gets an endpoint based off of the InternalSignalR key.  Once it does that it goes through and removes all old hubs and adds new ones.  The rest of the methods should be pretty easy to understand. 

Sending a message

When we want to deliver a message to a specific player it’s very easy to do so:

In this case, we’re first getting access to the only PushNotifierGrain ever used (we’re always using the one with the ID of zero).  We’re then pulling out all of the players in the current room and getting their primary key (a GUID created with the above mentioned cookie).  We can then call the SendMessage method on our PushNotifierGrain and pass in the message we want to deliver and the Guid we want to deliver it to.  Once we call that, the PushNotifierGrain loops through all of the Hubs that it can connect to and sends the message to that hub.  This means we’re sending our message to every hub (so each Web Role).  It’s then up to the hubs (web role) to deliver the message if a client has registered with the hub with the cookie.  So in the end only one hub will actually deliver the message down to the single client that should receive it!

The hard part: Exposing the endpoint

As I mentioned up near the top, it was pretty easy to take most of that from the GPS Tracker sample and adapt it to AdentureTerre.  However, pushing it to Azure lead to an issue:  there was no connection open for the Worker Roles to talk to the Web Roles.  I spent way too much time trying to figure this out.  The key to figuring out the problem was the name of the endpoint we’re looking for in the RefreshHubs method: InternalSignalR.  This didn’t exist anywhere.  As it turned out, this needs to be specified in the Azure deployment project’s ServiceDefinition.csdef file.  You just need to add a new internal endpoint to the Site Bindings and the Endpoints:

Summary

And that’s pretty much it.  Now not only can we “talk back” to our clients from the web but we can trigger updates from our Grains as well.  Our application can be really interactive now.  To see the SignalR stuff in action, all you need to do is change the movesRandomly flag of any of the characters to true.  Then if you’re in the same room when a character tries to enter or leave that room, you’ll get a message pushed to you!

Categories: Azure, Games, Web
Bookmark and Share
First Article