A project I have had in mind for a very long time is a MMORPG. It may sound a little bit stupid to build a MMORPG alone, and I probably won't succeed at it, but the process in itself is a nice way to learn many critical aspects of game development. I don't mean I will build an actual MMORPG, I just mean I will try to see how to develop the technical skeleton needed for a HTML5 MMORPG
Until now, I have worked on a few projects that had MMO aspects (my internship on kawipark was on a MMO, and my last project had many similarities to an MMO from a technical point of view).
The problem with your typical gameobject hierarchy
The most critical part of MMO development (and I actually think, any kind of game development) is data. Data is a big large thing, and so is a game. You have a massive amount of all sorts of content that are linked to each other in many different ways. Be it quests, items, scripting, levels or whatever, you'll have a hard time coordinating everything.
All of that data will evolve during development (and even after development in the case of online games), which means you just can't know what will be in your game before you have finished it. It is like a physical law, you won't avoid it and if you've made a few games you know that.
Even more problematic is the fact that when you build your gameobject structure, you will quickly notice that some of the data needs to be on many different objects. Because of that, your solution in OOP is to make extensive use of inheritance.
From this random hierarchy, found on google : imagine you want some vehicles to be background objects: You have to modify the whole game hierarchy, or maybe duplicate some code, and then debug the consequences. Now imagine with hundreds of object types.
As you see, OOP may end up being extremely redundant in game development. You have two choices: either you will overload every gameobject with data they don't necessarily need because it is more convenient, or you will have an incredibly big nested spider-web of class hierarchy.
In the end, all that unnecessary complexity makes the development less flexible. Every type of object is so complicated that creating a new game element is a tricky, frustrating and redundant task.
The Gameobject as an aggregation of components
A solution to the problems of OOP has appeared these last years and is quickly gaining in popularity. It's the Entity-Component system.
The idea is to forget the vertical structure of OOP (class1 inherits from class2 which inherits from class3...) and to work with an horizontal structure.
Instead of having gameObjects that are nested containers for data and code, you have entities. Entities are an aggregation of component - that is, they are just a reference to a list of components. Nothing else.
Components are the data. You have a component for each type of data your game have. Classical components would be a position, or a renderable component. Components are pure data. They don't contain any code
So what's the use for it? Well the idea is that you can now define your gameobjects as a combination of components you have developped. Some examples :
- The player has an input, position, physics, renderable, statistics, and inventory components
- A bullet has a position and physics components
Now, instead of having to hack OOP into an inheritance tree, you just have to create game elements by combining game pieces.
Systems : Independant pieces of game logic
So you may start to wonder where is the code in all that. Well it is in the systems.
Systems are routines that continuously check game components and act on them. This is where all the code is.
For example you can have a Physics system. This system will take all the "Physics" components and run the physics engine code on them. By having every component fully separated from the rest of the data, the systems can act independently on the components they want without risking conflicts.
And this is why the Entity System is so powerful: instead of trying to coordinate classes together and trying to initialize everything in the good order and all, in an Entity System, you just have independant data that are modified by stand-alone systems.
Our mind likes to put things in boxes. What makes game programming so complicated is that every box of a game are, to some extent, interdependant (the inputs acts on objects, that will trigger physics, that will trigger animations, that will have to be rendered). Add networking to it and welcome to hell. The Entity System does an extremely good job at keeping things separated in an efficient and flexible way.
If you want more informations on ES and why it is a good idea for MMORPG development, check this long post series. Most of what I know about Entity Systems comes from this post series, and I may reference to it later in my post because he does a much better job than I would at explaining all this.
Implementing an Entity System
As stated in the post series, the best way to represent an ES is a database.
The reason for this is that the very essence of an Entity System is a relational database. Entities are nothing more than the definition of relations between components.
So one great way of implementing this is in a SQL database. If you don't know anything about relational database or SQL, you should read a few quick tutorials about how all this works. The idea of SQL database is basically that datas are stored in Excel-like tables, with columns representing categories of data and rows representing data entries. Using SQL gives us the possibility of using powerful SQL requests to select the data our system needs to use. Let's see some examples that actual game systems could use:
SELECT * from physics_data WHERE (material='solid') SELECT * from player_data WHERE (class='ranger' AND agility>120 AND level=60)
In games, we often have to select some parts of game objects lists depending on arbitrary criteria (as in the two previous requests). In OOP, this is extremely hard to manage because the way data is stored forces you to just loop through some arrays, test if it has what you need, and then clone the results.
But SQL is meant to handle that sort of needs, so this is just natural to use that.
In part 2 of this post, I will explain how I tried to implement a basic ES structure in a Node server and a MySQL database. In the meantime, I highly recommend you to read the full Entity System post series, especially part 5 about the structure of the database.
You can safely jump directly to part 3 where I explain what structure actually worked for running the ES (hint: mongodb + caching)