Building MMO Virtual Worlds

In this article we are going to discuss the architecture of a MMO(*) Virtual World featuring the typical community tools (avatar chat, buddy lists, shop, games, trading tools, etc...) found in applications of this genre. (Habbo Hotel, Mokitown, Club Penguin...)

We will take an in-depth look at both the client (Flash / Flex) and server (SmartFoxServer) sides of the project and we'll discuss the best approaches to make the application easily extendable and manageable.

(*) = Massive Multiplayer Online (Game / Community / RPG)
There are literally dozens of acronyms that define the various genres of MMOs (MMOG, MMOC, MMORPG, MMOFPS...). Check Wikipedia if you're curious.

 

» A little background

habbo hotel

habbo hotel
In the past 2-3 years we've seen a conspicuous growth of Flash-based MMO Communities inspired by popular websites like Habbo Hotel, Mokitown and similar virtual worlds.
The idea behind these applications is to create a highly interactive world where users can not only meet and chat together, but also create their own customizable "spaces" (rooms, apartments, houses), play online games (both single and multi player), publish and exchange pictures and a lot more.

In the early days MMO communities were essentially based on "thick clients" (platform dependent executables, usually for Windows only) that users had to download to their local drives, install and run.

At the beginning of 2000 various startups were experimenting with technologies like Java and Shockwave to create similar applications and run them in a browser, making it possible to reach a wider audience and reducing the software dependencies to a single browser plugin.
Among those first experiments there were DeviousMUD which was later renamed RunEscape and Habbo Hotel.

Both MMOGs quickly became extremely popular, with millions of registered users from all over the world.
That experience inspired many other companies to research and experiment with similar technologies, including the emerging Macromedia Flash (today Adobe Flash).

Back in 2001-2002 Flash was rapidly gaining popularity but it was missing the same rendering power of its competitors (those were the days of Flash 5 and Flash MX). Additionally Shockwave had a dedicated server technology provided by Macromedia (Shockwave Multiuser Server) which helped simplifying the development and deployment of online MMOGs.

In just a few years things have evolved very quickly and today Flash is the leading platform for any type of browser-based applications and games, including MMOGs. The rendering speed has improved dramatically with the release of version 9 of the Flash Player and the ActionScript 3.0 languages provides a rock-solid platform for building any type of object oriented code.

As of today (February 2009) the latest Flash Player (version 10) is available for all 3 major operating systems (Windows, MacOS X and Linux-x86) providing a re-written virtual machine with new features like JIT compiling, support for binary sockets, advanced display programming framework and video support.

 

» The idea: VirtuaPark

In order to illustrate the architecture behind a similar application we will analyze the design of "VirtuaPark", a fictional community-driven MMO with customizable avatars interacting in 3D like environments (isometric), online and offline messaging system, shopping system and various multi-player games where users can challenge each others.

One of the crucial requirements for VirtuaPark is extensibility: we would like the project to be open to new features (new modules, games etc...) without major hassles, so that new components can be easily plugged to the existing code base.

The application will be 100% browser based, using the latest Flash Player.
Behind the scenes SmartFoxServer PRO and a MySQL database will do the hard work to keep everyone online and synchronized while interacting, chatting, playing etc...

The following diagram shows how the application modules are organized:

Application Overview

We have defined four main "modules" that will allow the user to access all the available features:

Each module in the application will be responsible for handling one specific task (avatar customization, game, user list etc...) and it will be able to send and receive events from the others. To give you an idea of the communication between modules check this example:

  1. the user clicks on Customize Avatar in the Main Menu
  2. the tool is loaded and launched in a new window inside the application
  3. the user modifies the look of his character and commits the change
  4. the tool sends a request to SmartFoxServer which in turn stores the new profile in the database and fires an event back to the Avatar Chat module so that everyone gets updated.

Side Note:

Creating a tile-based isometric engine for an Avatar Chat is not trivial and it may take several months of hard work to build it and integrate it with the server. Additionally a level-editor is usually needed to build the chat locations, adding more hours of development.
Because of this we have invested over 15 months of research and development to create a powerful and flexible Avatar Chat engine which integrates with SmartFoxServer out of the box.

The product is called OpenSpace and we suggest to take a look at the website and download the trial as it could save your development costs and time by different orders of magnitude.

 

» Shell-based application

It is time to dive into the architecture of the MMO and we'll do it (oddly enough) by starting on the client side. In order to make all the application modules work together in a seamless way we need a special module that acts as a glue for all the others. This special module will be called the "Shell" and it is represented in the following diagram:

Application Shell

The Shell Module will have a lot of responsibilities:

In order to develop the Shell and its modules you will have a good range of choices since SmartFoxServer supports both ActionScript 2.0 (from Flash 6 to 8) and ActionScript 3.0 (Flash Player 9, using Flash CS3 and Flex Builder 2).
If you are planning to use AS 2.0 we would also recommend to check the SmartFoxBits, a complete set of UI components that can dramatically speed up the process of creating Lobbies, Chat applications etc...

 

» Server side architecture

Now that we have defined the structure of the client side part, you are probably wondering what is going to happen on the server side: how will you handle the many possible requests, how are you going to manage assets, persistence etc...
Before we jump into the technical details of the server side extension, it would be better if we examine the components that we will use on the backend.

Again a diagram is probably worth a hundred words:

Server side architecture

Starting from low to top we have the client who connects through his browser to our VirtuaPark website. The website together with all the swf files and other assets can be comfortably handled by the Jetty web server embedded in SmartFoxServer.
With the embedded server you can easily serve static contents and create dynamic web pages using regular Java/JSP servlets or with the help of an integrated Python interpreter, to speed up the process.

The Server Side Extension will handle all the requests coming from each module, avatar chat and games plus it will access the database server to store and retrieve the user data, application status and whatnot.
In this particular scenario an ORM tool is highly recommended to help simplifying the access to the persistent data and make your server coding easier. Hibernate and IBatis are probably the most popular in the world of Java, but there are many others that you can check.

Another important aspect of ORM tools is that they provide a layer of abstraction between your application logic and the actual database server, making your Extension code independent from the DB technology. If for any reason you need to migrate from a database technology to another one it will be very simple to perform the switch and your code won't be affected.

SmartFoxServer allows developers to easily integrate such tools with both Java extensions and script extensions (ActionScript and Python). If you plan to use the latter you'll be able to directly access all the ORM objects from your scripts without the need of writing additional Java code.

To give you an idea of how powerful is the mix of scripting languages (Python in this case) with an ORM like Hibernate here's a snippet of code that shows a simple login method that retrieves a user from the database and access a few of its properties:

  1. session = HibernateFactory.openSession()
  2. tx = session.beginTransaction()
  3.  
  4. q = session.createQuery("from Users where nick = :nick and pass = :pass")
  5. q.setParameter("nick", nick)
  6. q.setParameter("pass", pwd)
  7. res = q.list()
  8.  
  9. # If the record was found...
  10. if res.size() >= 1:
  11.    
  12.     # Get the record
  13.     user = res.get(0)
  14.    
  15.     type = user.getMemberType()
  16.     gender = user.getGender()
  17.    
  18.     ...
  19.     ...

Hibernate allows you to query the objects in the database using a SQL-like language called HQL. As you can see instead of writing long SQL statements we just need to specify the criteria for our search. Once the object is retrieved we can access all its fields (including those that are mapped on linked tables) with simple getters and setters.

 

» The Server Side Extension

The Server Extension is the core of the application and probably the most complex part to build. As we have outlined in the previous diagrams we will run VirtuaPark in its own Zone and use a single extension plugged at Zone-level.

( If you're not familiar with the basics of the SmartFoxServer framework we would suggest you to pause the reading and review the articles found at Chapter 4 of our documentation ).

The first problem that we need to face when building the extension is how to organize the many requests that each client side module can send to the server.
An efficient solution to our problem is organizing the Server Extension in modules as well, just like we did on the client, and make them handle the specific requests coming from each client side module. (Chat module, Shop module, Game module etc...)

The following is a visual representation of the solution:

Extension Modules

As you can see from the diagram, the main Extension file will act as a dispatcher for the other modules, which are essentially custom classes designed to handle the requests of the client modules.

In order for this mechanism to work we need to establish a naming convention between client and server for the request names. As you may remember each Extension message sent and received by the server has a cmd property which identifies the command (request) name.

For our VirtuaPark we will be using the following convention:

moduleName##requestName

where:

Here are a few examples of requests based on the above convention:

chat##moveAvatar
profile##storeData
shop##buyItem

The following Python code example should clarify the whole process:

  1.  
  2. class ChatModule(object):
  3.     def handleReq(self, cmd, params, who, roomId):
  4.         print "Handling Chat Request: ", cmd
  5.  
  6. class ShopModule(object):
  7.     def handleReq(self, cmd, params, who, roomId):
  8.         print "Handling Shop Request: ", cmd
  9.  
  10. class GameModule(object):
  11.     def handleReq(self, cmd, params, who, roomId):
  12.         print "Handling Game Request: ", cmd
  13.        
  14.        
  15. handlersTable = {}
  16.  
  17. def init():
  18.     global handlersTable
  19.    
  20.     print "Initializing"
  21.    
  22.     # Instantiate modules
  23.     chatModule = ChatModule()
  24.     shopModule = ShopModule()
  25.     gameModule = GameModule()
  26.    
  27.     # Add modules to the handlers table
  28.     handlersTable["chat"] = chatModule
  29.     handlersTable["shop"] = shopModule
  30.     handlersTable["game"] = gameModule
  31.    
  32.    
  33. def destroy():
  34.     print "Stopping"
  35.  
  36. #
  37. # Handle client requests
  38. #
  39. def handleRequest(cmd, params, who, roomId, protocol):
  40.     separatorPosition = cmd.find("##")
  41.    
  42.     # Look for the separator
  43.     if separatorPosition > -1:
  44.         moduleName = cmd[0:separatorPosition]
  45.         reqName = cmd[separatorPosition + 2:]
  46.        
  47.         # Get the handler module and pass the request parameters
  48.         if handlersTable.has_key(moduleName):
  49.             handler = handlersTable[moduleName]
  50.             handler.handleRequest(reqName, params, who, roomId)
  51.            
  52.         else:
  53.             print "Unknown Module: ", moduleName
  54.    
  55.     else:
  56.         print "Invalid request: ", cmd
  57.    
  58. #
  59. # Handle server events
  60. #   
  61. def handleInternalEvent(evt):
  62.     pass
  63.     

We have defined 3 simple classes (ChatModule, ShopModule and GameModule) that represent the chat module, shop module and a game module respectively. Each class has a handleReq method that will be invoked by the main Extension file.

In the init() method of our Extension we instantiate all three classes and we add them to a global dictionary called handlersTable. ( A dictionary in Python is the equivalent of an associative array / HashMap )

When a client request is received by the handleRequest() method we will do the following:

If you prefer to use Java for your Extensions you should be able to re-create the same code structure by defining an interface that all module classes will implement.

  1. public interface ModuleRequestHandler
  2. {
  3.     public void init();
  4.     public void destroy();
  5.     public void handleRequest(String cmd, JSONObject params, User user, int roomId);
  6. }

 

» Conclusions (Part 1)

Now that we have defined the general architecture of both client and server side you can see how the main goal of our VirtuaPark design (extensibility) is successfully achieved. By using a modularized architecture on both sides of the application we will be able to easily add new features and games to the virtual world.

The 2nd part of this article will analyze the remaining parts of the puzzle and provide further advices for the development.

 


Proceed to part 2 of the article »