Workshop 3: Multizones


In this Workshop you will learn how to seperate a big MMORPG world into several zones and how you can switch between zones. It is required that you've read HowTo1 and the Simple 3D Chat Tutorial.

What are zones?


Zones are seperated areas of a big game enviroment. Normally every zone is on a seperate server. The giant game enviroment is seperated into several small levels and every level is assigned to a server.
For example: One zone is a city with a huge wall around it. From this city you can switch through a giant door into the outer area e. g. a harbour. Additionally you can switch into a secret cave if you go through a fountain. The city, the harbour and the cave are seperate zones.
If you switch from one zone to another, the connection to the server will be broken and established to the new one. Additionally the new level that is managed by the new server will be loaded.
Certainly now it's clear to you why zones are needed: With zones you can split the traffic to several servers and save traffic on the clients. Because players that are in zone A don't receive data from players in zone B a giant game environment with hundreds of players is split into several small areas with less players in it.

Beside the servers that manage the different zones, MMORPGs also have a database server that manages the player data. With ANet you can implement this with a conventional SQL server. With http_pos() and php you can get access to the database. Access over php is more save than direct access.

creating zones


As mentioned above a zone is nothing else than a server with a level. So we create a zone as following:

//Lite-C:
function init_zoneA()
{
level_load("zoneA.wmb");
wait(3);
enet_init_server(2300,32,"");
enet_set_level("zoneA.wmb");
}

function init_zoneB()
{
level_load("zoneB.wmb");
wait(3);
enet_init_server(2301,32,"");
enet_set_level("zoneB.wmb");
}

init_zoneA() loads the level of the according zone and initializes a server after that. enet_set_level() tells our server which level is loaded. In reality every zone will be started on an own machine. But to allow testing and working with zones it's easier for us to open a new window/application per zone.
If we want to open 2 zones we start our game and call init_zoneA(). After that we open the game a second time and call init_zoneB() in the new window. You have to notice, that you have to initialize the two servers with different ports because you can use a port only once per machine.

connect/change zones


Now that we know how we can create zones we, will look into how we can connect with a zone and how we can change between them:

//Lite-C:

function connection_astablished(var sender, char* msg, var length)
{
level_load(msg);
wait(3);
enet_ent_synchronize();
}

function synch_complete(var sender, char* msg, var length)
{
error("Connected with ZoneA!");
}
function zoneA_connect()
{
enet_clset_event(EVENT_CONNECTED, connection_astablished);
enet_clset_event(EVENT_SYNCHRONIZED, synch_complete);
enet_init_client("localhost",2300,"");
}

You should already know this code from the Simple 3D Chat Tutorial: A client is created that connects with the server on the localhost over port 2300 (this is Zone A in our case). Once the connection to the server is established, it loads the level that is loaded on the server and the entities are synchronized. When the synchronizing is complete it gives a "Connected with Zone A!" message.
If you want to connect with Zone B you have to change port 2300 to port 2301. If Zone B would be on another machine you would have to use the ip of the machine.

Ok, we know now how we can connect with a zone, but how can we switch between them?

//Lite-C:
function disconnect()
{
enet_host_destroy();
level_load("");
wait(3);
}

For changing the connection we need another function: disconnect(). The function destroys the current client and loads an empty level so that all running entity functions are stopped. Instead of enet_host_destroy you should prefer sending an event to the server and the server should then use enet_disconnect_client for the disconnection. The disadvantage of enet_host_destroy is, that the client is simply destroyed and no message is sent to the server that the connection is lost. Because of this it will take some time until the server knows that the client disconnected!
If we want to switch from Zone A to Zone B we only have to call disconnect(). After that we connect to Zone B like in the example above.