Xenocell: Server magic
by Konrad Kiss · 03/13/2009 (8:00 am) · 25 comments
I am creating a game that is a lot like MMOs out there. It runs several missions at the same time on many dedicated servers, and players are transmitted between these servers as needed.
The game revolves around players in teams fighting for resources on and beneath the face an alien planet. The main game field is a huge valley full of abandoned portals that lead to rare resources on the planet. The more portals a team controls, the more resources a team gets each hour. Read more on the website, or my previous blogs here and here.
I did not mean to dive into the game much, but this was needed for you to see why I designed the server architecture the way I did.
I refer to dedicated game servers as instances - a term probably familiar from World of Warcraft to many of you. Each of these instances run one game zone (or mission). My game distinguishes between three types of zones:
- persistent, singleton zones started at world start (such as the main game world)
- non-persistent, instanceable zones started on demand (such as cities in the world)
- non-persistent, singleton zones started on demand (such as resource sites)
One game world is basically a set of many servers. Just as if they would be different games, several worlds can be replicated by creating the same architecture. You can view a mockup of the architecture here:

The road that lead to this structure was pretty rough. I had my list of things I needed to get done, but I was not sure about how I'd go about doing that.
I've spent numerous nights to prepare an architecture for the servers that fulfills the following requirements:
It is self-balancing
New non-persistent server instances are started and stopped within seconds on demand. If a city is too crowded, another instance is started and the player is given the opportunity to switch over to another instance of the city. Also, if an instance times out because of a crash or hardware failure, new instances must be started in the place of existing ones while players are transmitted to other instances of the same zone.
It uses the database efficiently and not unnecessarily
Data caching is a very important aspect of my solution. Most of the data the game requires can be cached - item stats, skill and quest descriptions are good examples. These data should be cached once and then provided to the game servers without having to access the database. When any such data changes, the cache would be automatically cleared, so a new one can be created at the next time the data is queried for.
The server cluster can be easily expanded
When a new server is prepared to be added to the cluster, registering it as a resource is just adding it to the list of servers in the database. Once there, the master server will take care of managing instances running on the new hardware.
This is very important in preparing for a sudden rush of players that would otherwise make the game kneel down and crash in a matter of minutes.
Available server resources can be measured
It is possible to define ports where instances can be started on each hardware. The master server will take care of putting the available ports into a pool where the server with the least relative load will get to start the next instance when needed.
So by counting the number of overall and available ports and players on each server, the master server can guess the load percentage of each game server, and act accordingly.
Data retrieval runs as a separate thread
The game server must never wait for data. Whenever data becomes available to the game server, the data is processed. This way the database will not become a bottleneck when many queries, or even unoptimized queries are run. This gives me just a little extra to be able to further optimize the database without having effects that affect players too much and would stress the hell out of me.
...
Most of this architecture is already functional. I am now finishing it all up with the XML data gateway / relay and caching facility. My investor is preparing our servers as I write this, and I'm hoping some of you could help me with alpha testing starting next month. If you are interested, sign up on the Xenocell website.
I will be sure to take only small steps. Starting with only a few features, and adding more one by one.
As closing words, to anyone brave enough to plan an MMO and not be let down by the anti-MMO craze, here are a few tips:
1. Until about two weeks ago, I've worked on the game without having a dedicated server. If you are making a multiplayer game, make sure you start by separating client and server, otherwise you will have many problems later on. It is important to keep in mind that local client to a non-dedicated server will be able to access many server variables without having to scope them to the client. That causes a huge number of headaches if you don't pay attention.
2. Another tip is that when creating any object that you need each client to have one of, never name them upon creation.
Let's assume you name a clients camera Cam when the client joins the game. When the next client joins the game, his/her camera will also be called Cam on the server. This causes first client's cam to be invalid, and the client will get a nice pink screen. (This has happened to me. :)
If you are interested in more information about certain parts of the Xenocell architecture in detail, let me know. And as always, constructive criticism is more than welcome.
Thank you for reading through.
--Konrad
The game revolves around players in teams fighting for resources on and beneath the face an alien planet. The main game field is a huge valley full of abandoned portals that lead to rare resources on the planet. The more portals a team controls, the more resources a team gets each hour. Read more on the website, or my previous blogs here and here.
I did not mean to dive into the game much, but this was needed for you to see why I designed the server architecture the way I did.
I refer to dedicated game servers as instances - a term probably familiar from World of Warcraft to many of you. Each of these instances run one game zone (or mission). My game distinguishes between three types of zones:
- persistent, singleton zones started at world start (such as the main game world)
- non-persistent, instanceable zones started on demand (such as cities in the world)
- non-persistent, singleton zones started on demand (such as resource sites)
One game world is basically a set of many servers. Just as if they would be different games, several worlds can be replicated by creating the same architecture. You can view a mockup of the architecture here:

The road that lead to this structure was pretty rough. I had my list of things I needed to get done, but I was not sure about how I'd go about doing that.
I've spent numerous nights to prepare an architecture for the servers that fulfills the following requirements:
It is self-balancing
New non-persistent server instances are started and stopped within seconds on demand. If a city is too crowded, another instance is started and the player is given the opportunity to switch over to another instance of the city. Also, if an instance times out because of a crash or hardware failure, new instances must be started in the place of existing ones while players are transmitted to other instances of the same zone.
It uses the database efficiently and not unnecessarily
Data caching is a very important aspect of my solution. Most of the data the game requires can be cached - item stats, skill and quest descriptions are good examples. These data should be cached once and then provided to the game servers without having to access the database. When any such data changes, the cache would be automatically cleared, so a new one can be created at the next time the data is queried for.
The server cluster can be easily expanded
When a new server is prepared to be added to the cluster, registering it as a resource is just adding it to the list of servers in the database. Once there, the master server will take care of managing instances running on the new hardware.
This is very important in preparing for a sudden rush of players that would otherwise make the game kneel down and crash in a matter of minutes.
Available server resources can be measured
It is possible to define ports where instances can be started on each hardware. The master server will take care of putting the available ports into a pool where the server with the least relative load will get to start the next instance when needed.
So by counting the number of overall and available ports and players on each server, the master server can guess the load percentage of each game server, and act accordingly.
Data retrieval runs as a separate thread
The game server must never wait for data. Whenever data becomes available to the game server, the data is processed. This way the database will not become a bottleneck when many queries, or even unoptimized queries are run. This gives me just a little extra to be able to further optimize the database without having effects that affect players too much and would stress the hell out of me.
Most of this architecture is already functional. I am now finishing it all up with the XML data gateway / relay and caching facility. My investor is preparing our servers as I write this, and I'm hoping some of you could help me with alpha testing starting next month. If you are interested, sign up on the Xenocell website.
I will be sure to take only small steps. Starting with only a few features, and adding more one by one.
As closing words, to anyone brave enough to plan an MMO and not be let down by the anti-MMO craze, here are a few tips:
1. Until about two weeks ago, I've worked on the game without having a dedicated server. If you are making a multiplayer game, make sure you start by separating client and server, otherwise you will have many problems later on. It is important to keep in mind that local client to a non-dedicated server will be able to access many server variables without having to scope them to the client. That causes a huge number of headaches if you don't pay attention.
2. Another tip is that when creating any object that you need each client to have one of, never name them upon creation.
Let's assume you name a clients camera Cam when the client joins the game. When the next client joins the game, his/her camera will also be called Cam on the server. This causes first client's cam to be invalid, and the client will get a nice pink screen. (This has happened to me. :)
If you are interested in more information about certain parts of the Xenocell architecture in detail, let me know. And as always, constructive criticism is more than welcome.
Thank you for reading through.
--Konrad
About the author
Lead Developer at Bitgap Games (www.bitgap.com) currently working on Xenocell (www.xenocell.com) a massively multiplayer action strategy game based on Torque 3D technology.
#22
www.ibm.com/developerworks/architecture/library/ar-powerup1/
04/19/2009 (9:21 am)
I found a resource related to this. IBM created a "simple yet powerful mmo game architecture" using Websphere and TGEA, and created a nice three-part series of articles describing the process:www.ibm.com/developerworks/architecture/library/ar-powerup1/
#23
My only concern about it is the ODBC connection. I'm not a fan of ODBC - though it depends on the driver I guess, for me, ODBC brings back very sour memories under a large strain. Since ODBC is still around, I can only guess that it was not entirely ODBC's fault after all.
Still, I prefer OLE DB over ODBC.
04/19/2009 (10:10 am)
@Mason: Yep, I saw that article, and I think it's really cool. They event took the extra mile and posted this as a blog here on GG.My only concern about it is the ODBC connection. I'm not a fan of ODBC - though it depends on the driver I guess, for me, ODBC brings back very sour memories under a large strain. Since ODBC is still around, I can only guess that it was not entirely ODBC's fault after all.
Still, I prefer OLE DB over ODBC.
#24
Game sounds like fun too, signed up for Beta. :)
06/11/2009 (9:10 am)
Very nice write up and thread.Game sounds like fun too, signed up for Beta. :)
#25
06/11/2009 (9:13 am)
Thank you Charles! See you in beta next month! :)
Associate Konrad Kiss
Bitgap Games
I've even separated sql statements from the game server, so in effect, it only sends query aliases - much like stored procedures - so even queries are completely separated from the game server.
This allowed me to do something really cool which I like to call shared resultsets. This is basically that if a new data query is made while the very same data is already being asked for, then the new query is not sent to the xml gateway - instead, the object that requests data is added to the ongoing data query object as a receptor that will receive a copy of the data when it arrives. The data has a counter for the receptors. Every receptor will try to delete the dataset once it's not used by the receptor anymore, but only the very last one will actually delete it - the rest will just decrease the counter on the dataset.
I'm really excited about this tech, I'm expecting it to save me some sleepless nights.