Play the game at
Check the source code on Github.

Monday, 9 March 2015


Modularity is a very important concept when creating a large-scale project. It is the main reason why so many projects fail as they reach a considerable size.

Modularity means to minimize the relations between modules (aka files) and to make sure modules perform a precise job. Doing so makes it easier to add new features but more importantly, makes it easier to remove or alter them.

Modularity is by no mean absolute. Making everything 100% modular is impossible and impacts negatively the performance. Classes need to interact between each others but you need to make sure they interact correctly. It is important when refactoring a project to first dress the list of what needs to be modular and what doesn't need to.

The first question to ask is what will grow in size as the HTML5 MMORPG grows and what is the most likely to change. Those need to be as modular and independent as possible to make changes as easy as possible. Most of the time in a game, the maps and quests are the main concerned elements.

Typical Quest and Map Structure:

File item
info about item for quest 1
info about item for quest 2

File npc
info about actor for map 1 quest 1
info about actor for map 1 quest 2
info about actor for map 2 quest 1
info about actor for map 2 quest 2

File map1:
modify questVariable of quest 1 when talked with
modify questVariable of quest 2 when talked with

File map2
modify questVariable of quest 1 when talked with
modify questVariable of quest 2 when talked with

File quest1
logic concerning questVariable

File quest2
logic concerning questVariable

Note: A real structure for a HTML5 MMORPG is a lot more complex than this.

This structure seems modular. The file item handles items. The file actor handles actors. The map files handle maps and quest handles quests. But there's still a big problem in this structure. There is no way to know what elements a quest depends on other than checking in every map files, every item files, every actor files etc...

When the game has less than 10 quests, it's not a big deal. But when the game has 100+ maps, 100+ quests, 100+ npcs, 200+ items, and you want to remove a quest, the task becomes really time consuming and most likely, some parts will be forgotten.

There is also a big naming issue. If you don't use prefix for quests, you may name an actor with the same name than another actor, causing very hard to detect errors. If you want to create a new quest that uses the questVariable killMonsterCount, you would need to check in every quest file and make sure it's not used yet.

In Raining Chain, I opted to put all the data needed by a quest in the same file. Every element (item, equip, ability, dialogue, npc, map, variable, highscore, challenge) created comes automatically with a prefix to prevent collision. Adding an element in an external map is also done within the quest files.

actor quest1-1
map quest1-1
item quest1-1
item quest1-2

actor quest2-1
map quest2-1
item quest2-1
item quest2-2
add actor to map quest1-1

Using this system makes it very easy to remove a specific quest. All you need to do is remove the file and everything related to it is gone. However, doing it that way creates a relation between the quest file and every part of the game engine. So in theory, it is not modular... A modification about game engine may end up forcing you to go through every quest file. This means a solid Quest API is required in order to minimize the impact of future game engine changes. I will cover the Quest API in another post.

Preventing DDOS

Raining Chain HTML5 MMORPG uses Socket io library for websockets. Even though it is a great library to handle websockets, it is very vulnerable to DDOS.

A player could open the console with F12, type
while(true) socket.emit('eventName',bigObject);
and crash your server (or at least slow it down).

This means you need to implement a system to disconnect a player that sends too much data.

On the server, instead of using:

io.on('connection', function (socket) {
 socket.on('eventId', function (data) {
 socket.on('eventId2', function (data) {


handleSocket = function(socket,eventId,data){
 if( - socket.lastEventTimestamp < 5){
  socket.disconnect(); //optional
 socket.lastEventTimestamp =;
eventDb = {

This is the most simple system. One could implement different thresholds for every event and take into consideration the size of the data sent. Instead of disconnecting the socket when sending too fast, one could keep track of how many times it has happened and only disconnect if it happened more than 100 times in the last minute.