I participated in my first complete, engaging game, I played around with some cool ideas, learnt some asset creation techniques, bolstered my Unity knowledge, and had quite a lot of fun.
The theme of the contest this time was “It’s dangerous to go alone! Take this.” I considered that if it was dangerous to go alone, then it must be safer to go together. I didn’t think it would be feasible to develop a full multiplayer game in 48 hours, but I could develop a game that was ostensible singleplayer while having some kind of interaction between all the people who are playing it. Kinda like an MMO, but where all the other players are invisible. (I considered trying to explain this within the game in terms of quantum interference and Everett MWI or something, but I didn’t get time).
Naturally, in order to have players interact, I’d need some kind of server that could co-ordinate that interaction. Initially I thought I might be able to use IRC, but, alas, I wanted the game to run in the browser, and there are security implications that make connecting to IRC from inside the browser window impossible, at least without some kind of proxy server. If I wanted to run in the browser and also have multiplayer elements, I’d need to run my own server somewhere.
What’s the simplest way to get custom code running somewhere Internet-accessible for the duration of the competition? I couldn’t run it from home – my home connection’s upload bandwidth is terrible. I didn’t really want to sign up for a full shell host; most of them have a minimum term of one month, and I only really need half of that.
I decided to try running my server on Amazon’s Web Services infrastructure, specifically their Elastic Compute Cloud (EC2). The multiplayer server is super-simple – a single instance that stores everything in memory – so I didn’t need most of the things that EC2 have on offer, but the ability to spin up a fresh Linux install in seconds, put my server software on it, and just turn it off when I’m done was very attractive.
I’m also within my first year of AWS usage, which means I qualify for their free usage tier: a 1.0 GHz Xeon processor, 613MB of memory, 10GB of storage, and 15GB of bandwidth each way in and out, free for a year. Hard to beat free.
I can’t write this post without mentioning the recent outage they had. Simply put, it doesn’t worry me. Amazon’s analysis of what went wrong is very thorough and shows their competency; shit happens, and when it does, the important thing is how it’s handled. That this kind of chain reaction can happen is interesting, but I’m confident that they’ll make the changes they need to make in order to interrupt the chain should anything like it happen again. Remember, Amazon dogfood this stuff; problems in their cloud don’t just affect their cloud customers, they affect Amazon.com itself.
Creating the Instance
The first step was to create the instance (the ‘virtual machine’ that I was going to use). From Amazon’s EC2 management page, I hit the ‘Launch Instance’ button, then picked the “Basic 32-bit Amazon Linux AMI” from the list. The page walked me through configuring how big I wanted the instance to be (“Micro” size to get the free tier) and which ‘zone’ I wanted it to be hosted in (I didn’t care). There were a couple more pages of config where I could turn on things like advanced monitoring and enter custom metadata, but I didn’t need any of that.
Next it had me create a key pair for the machine. All the Amazon machine images are preconfigured with key-pair based SSH, and it’s really a much nicer method than using passwords anyway, so I had it create a key pair for me and downloaded the private key to my own machine.
Then it asked me to pick a Security Group. Security Groups are used for configuring the firewall; you might have one security group that allows SSH and HTTP, another that allows FTP, a third that allows only SSH, and so on. I put the machine in a ‘default’ group. Finally the wizard had me quickly review my settings; after a quick check, I hit OK, and the machine began booting.
It was ready within about 10 seconds.
Now my machine was running, I wanted to connect to it and start working.
The first thing was to enable SSH on the firewall. The default security group settings are such that machines within a security group can connect to each other on any port, but there’s no access from the outside world by default. I went to the security group page, picked my ‘default’ group, and went to the ‘inbound’ tab. I picked ‘SSH’ from the ‘create a new rule’ dropdown, and left the source at 0.0.0.0/0 (i.e. any source). Hit Add Rule, hit Apply Changes, and the firewall was instantly reconfigured.
Now I just needed to get key-pair authentication working. My SSH client of choice on Windows is, of course, PuTTY; the private key file Amazon had given me isn’t something that PuTTY can read by default, but PuTTY companion program PuTTYgen can import it and convert it to PuTTY’s native format. Then I just had to set up the connection: the required settings in PuTTY are a bit hidden, but I set the auto-login username on the Connection->Data page to ‘ec2-user’, and pointed the private key file on Connection->SSH->Auth at my private key file. Then I just had to punch in the IP address of my instance – visible on EC2′s management page – and I was connected.
This entire process, from deciding to use EC2 to being connected to my very own instance over SSH, took about 15 minutes.
I wanted to write my server in C#, just like the rest of my game, so I’d need the ability to compile and execute C# code on my server. I also wanted to use some of the server-side tools that Unity provides for dealing with things like cross-domain security policy, and they too are written in C#. Even if I compiled everything on my own machine, I’d still need the Mono runtime to be present in order to run them.
I was all set for a difficult and time-consuming process of building things from source or something, but then I found a perfect set of instructions on StackOverflow. Other than needing to prefix a few of the commands with ‘sudo,’ they worked flawlessly.
…and we’re away
That’s basically all I needed to do, beyond writing the server itself. I needed to open a couple more ports in my Security Group – one for the game server itself, and port 843 for the crossdomain.xml policy server – but that was basically it.
I’ve not set up any persistent storage for my instance. Other than the mono install and the server software, I’ve not changed the base AMI, and it’d take me 10 minutes to reapply those changes. In any case, I’m not planning on shutting down the instance until after the contest, at which point it won’t matter.
If you want to run a custom game server and you don’t want to do it from home, AWS may well be worth checking out: it’s extremely easy to get going, free for most of the things that a small game would need (for a year, at least) and scales nicely if you’re looking at doing something bigger.