Network Architecture and Integration in Games
The Background Babble
When I started this blog I promised myself I would post once a week, I have already broken that promise after only two posts.
The last couple of weeks have been extremely busy for me; I tidied my apartment properly for the first time since I moved in, several new games have appeared on the market and I've been trying to keep up with the influx of awesome TV shows.
In my last blog post I covered some of the good and bad things which have been introduced as games become more concurrent. I also stated that games are now expected to have online multiplayer as standard. The problem is, if you don’t have anyone with network programming experience, it’s often a minefield.
The last month or so has seen some problems which still exist with online games resurface in the form of server queues and simple unavailability in a couple of new titles.
Since I began my career in the world of game networking, I have worked with three networking systems which couldn’t be more different from one another.
The very first system I worked with was for a massively-multiplayer online role-playing game. This system was, as you might expect, strictly client-server.
The second networking system I worked with was for a racing title. Unlike the MMO, this system used a peer-to-peer architecture.
Finally, and most recently, we have the third system for an Action RPG. This system is a hybrid between peer-to-peer and client-server.
One of the most frequent questions I get asked is “Which architecture should I use?” it’s a valid question and a very interesting one. It’s a particularly nasty question for engine developers as there simply is no “one size fits all” solution for game networking. The true answer is “it depends”.
Peer-to-peer architecture allows all peers to communicate directly with one-another, sharing and managing their own resources. You can find out more at http://en.wikipedia.org/wiki/Peer-to-peer.
Client-server architecture on the other hand has one or more central authoritative peers (aka servers). You can find out more at http://en.wikipedia.org/wiki/Client-server. I won’t go into a huge level of detail as those articles describe both architectures very well and it’s somewhat outside the scope of my blog.
Peer-to-peer architecture generally allows peers to propagate information more quickly as they can communicate directly with other relevant peers. One of the big advantages of a peer to peer system is the ability share ownership and responsibility between peers. Ownership of world objects can literally be spread between peers, and when you need to do something to an object, you can request ownership from the peer that currently owns it. Peer-to-peer is also generally quite flexible; host migration is simple as there is no true host.
Peer-to-peer generally starts to fall down when security and control is important. A peer-to-peer system is inherently insecure. There is no authoritative server to make decisions, so in the case of disagreements peers need to arbitrate, which can become quite complicated. Peer-to-peer also tends to use more bandwidth. It is often the case that someone hosting a game has an internet connection that is suitable to do so, but with this architecture all peers share higher bandwidth. Methods to work around high-bandwidth generally include setting up relay systems, this starts to eat into the speed gains you get from the direct connection and is again, complicated.
Client-server architecture generally gives more control, this is extremely important in some kind of games. Client-server is heavily used in most first-person-shooters for this very reason. The server is in the perfect position to make decisions and treat all players fairly. A client-server architecture also gives you more security, having one authoritative point allows you to see exactly what is going on everywhere else and make informed decisions about cheating and other security concerns. Security is even more important in games such as MMOs where cheating is a very large concern and the majority of simulation such as NPCs is running on the server.
It follows that client-server is weaker at the things which peer-to-peer excels at and vice-versa. In some cases it lacks speed, as messages have to pass through the server and then to relevant peer. Client-server also makes it more difficult to implement seamless host migration and good shared ownership.
The above examples are not exhaustive and do not cover every implementation of both architectures so do not take those reasons as the only ones, do some research!
Not only has the network architecture itself been different, but so has the way it is integrated with the rest of the game. Unfortunately, networking is a very obtrusive system as it really needs to know everything that is happening on relevant peers to keep things ticking over correctly.
Another question that I hear frequently is “how do I write the code?” or “how do I lay out the systems?” again, a valid and interesting question. Again, there is no “one size fits all” solution.
I’ve seen some extremely clever and some extremely stupid things done in relation to game networking over the past few years. Some solutions are over-engineered to the point of insanity and others are tacked on to the side of the game in a very scruffy fashion.
The systems which are over-engineered tend to be written by one programmer throughout the lifetime of the project. That one programmer scurries around after everyone else and make’s their code network friendly. None of the other programmers are involved with the networking system and the network programmer basically has entire control.
The scruffy systems on the other hand, tend to appear when during the vast majority of production, there has been no network code. Very late on a large amount of the team focuses on getting online multiplayer working. This results in code which is essentially tacked on to the side of the game. Nothing in the game is designed to work over the network, so the code is littered with special case exceptions for certain systems.
Naturally you want to hit a balance between code which is too complexed and code which is messy, but this can be hard and needs the co-operation of every programmer on the team.
Solutions and best practices
There are lots of things you need to take into account when writing network code for games. The subject is quite deep and will only get more complicated as games try to do more and more online.
The best thing you can do is thoroughly research the best solution for your title. It’s also very important to get all programmers involved in writing code which is robust enough to work over the network; this helps you to avoid the integration problems I described above and leaves the network programmers to concentrate on the core network tech and architecture.
I plan to follow up this post with some more in-depth details about both the architecture and integration aspects of network code, but going on my previous record... that might be a while.