PIKKO SERVER MMO
uLink is by itself capable of being used for developing massively multiplayer online games (MMO games). Using the tools described in the previous chapters it is possible to build a zoned, large-scale game with many simultaneous players. However, uLink also has support for using Pikko Server (developed by PikkoTekk), a load-balancing networking technology that turns a regular server backend into a distributed cluster of servers working together to create a seamless world. The main difference between an MMO and a regular networked game is the amount of players able to interact together in the virtual world. In a regular client-server game there is only a single server for each game region, and the amount of players able to play in the region is determined by how many players the server can handle. Using Pikko Server to develop an MMO, on the other hand, there can be several servers working together to distribute the load in a single region, allowing for much greater numbers of players. This section will go through the details of how to use uLink to develop the network side of an MMO. It will not go over all the details of how Pikko Server works. To learn more about the inner workings of Pikko Server, see the Pikkotekk website. The same basic tools covered by the previous chapters are used for developing MMO games. However, there are some differences that have to be taken into account and, naturally, new functionality to be implemented and adapted to fit your game.Overview
Pikko Server is a load-balancer and distributor for online games, used for building MMOs capable of handling thousands of simultaneous players in the same area. It is not an engine - it is an external module that can be used in many different engines. Thus, games are not written in a special environment or language tailored for Pikko Server, but in the same way they were previously made using the same tools. Using the uLink integration it is straightforward to get started programming using Pikko Server. Pikko Server makes it possible to use several servers for governing a single region in a game. It dynamically distributes the servers over the region so that they each cover their own section of it along with the objects in that section. These servers are just normal servers written using uLink, but with some extensions to jack into the Pikko Server framework. Pikko Server works completely externally from the servers and coordinates them to make for an optimal distribution over the region. It is aware of the positions of the network objects in each server and of what region each server covers. When an object crosses a server's boundary, Pikko Server moves the object from the old to the new server. Clients do not see the underlying distribution of the region onto different servers - to them it will look like a single region. Pikko Server uses information from several servers to present the client with a consistent, seamless world. Before delving into the details of how to develop MMOs with uLink, let's take a look at the classic approach of structuring an MMO game and how Pikko Server can improve on this.The Classic MMO Approach
The structure of an MMO game is quite different from that of an ordinary, single-server based game. Since the world in an MMO is usually very large, it has to be spread out over many servers in some way. And since the number of simultaneous players in the world is usually also large, the load generated from them needs to be handled in some way. The usual approach for dealing with these problems is to divide the world into a number of zones, where each zone covers a static portion of the game world. Each zone is then handled by its own game server that takes care of all the players and actions in that region. The zones are typically isolated from each other, in that they only rarely communicate with other zones' servers (typically this is done when they need to move objects to or receive objects from nearby zones) and, more importantly, in that players cannot see the actions taking place in a nearby zone. When players walk into a new zone, they need to be switched from the old server to the new server. This normally induces a noticable delay for the player as the new zone is loaded and the old one unloaded. An example of zoning would be in an MMORPG where a town is one zone and a region outside the town is a separate zone. When walking from the town to the outside area, a loading bar appears to notify the player of the zone switch, and after that, all the players in the town disappear and the players outside the town appear. In addition to zoning, another important concept often used in MMO games is that of instances. Usually associated with MMORPGs, instances are akin to zones in that they are isolated portions of the world and can be handled by a separate server each. However, instances are used for creating many separate views of the same region of the world. Using the MMORPG example again, a certain dungeon in the world could be made instanced and thus spread over many game servers. Each instance would contain its own copy of the dungeon and act separately from the other instances. Upon entry to the dungeon, a random server could be chosen for the player. Many players could then visit the dungeon at the same time, but only players on the same server would be able to see and interact with each other.The Pikko Server Architecture
uLink using Pikko Server supports developing MMOs using the same techniques and overall architecture described above. The Peer-To-Peer chapter shows how zoning can be implemented by having several servers and handing objects over between them. Instances can be made in a similar way. While zoning and instancing work well for increasing the size of the world and the total number of simultaneous players in a game world, they have some major drawbacks. The maximum number of players that can interact with each other in a zone is still limited by how many players the server handling that zone can cope with. No matter how many servers are added, the limit for each zone will stay the same. And since you can't see the activities happening in other zones, this sets the limit for how many players you can see and interact with at the same time. Pikko Server offers a sophisticated approach for solving this problem by allowing a zone to be distributed over many servers. Each server handles a part of the players in the zone, and Pikko Server coordinates the servers to ensure a seamless distribution. The client doesn't notice this server-side distribution - from the outside it will still look like a single, contiguous area with players spread out in it. The difference is that there can be a lot more players. This is accomplished by Pikko Server working as a global distributor of networking data for the servers in a zone, deciding what part of the zone each server should handle along with the objects in it. From the perspective of Pikko Server, each server in a zone is called a cell server. A cell server is basically just a normal game server with some extra features to make it fit into the Pikko Server architecture. Pikko Server is aware of the location of all network game objects and of the regions handled by cell servers. As objects move around in the world, Pikko Server moves them between cell servers according to what regions are currently handled by which server. Moving an object from one cell server to another is called a handover. The handover functionality must be provided by the cell server according to a standard interface.Pikko Server's Operation
Seen from the point of view of the network, Pikko Server acts essentially as an intelligent router of traffic. Cell servers and clients begin by connecting to Pikko Server, and all of their traffic will thereafter pass through it. The traffic from a client will be routed to the cell server it is currently handled by. That client will get information from its current cell server, as well as other cell servers in its vicinity. Pikko Server sees to that clients get the information they need in order to be able to accurately depict the current world state. To keep Pikko Server informed of the state of the world, the cell servers periodically send updates on the positions of the objects in the cell server. This is taken care of behind the scenes by uLink and needs not be implemented by the programmer, although some parameters, such as the sending interval, can be configured to fit the needs of game. Using the position information and its local information on the regions handled by each cell server, Pikko Server notices when objects cross cell server boundaries and a handover is needed. When this happens, a handover message is sent to the cell server that the object left, requesting the state of the object. The cell server needs to handle this message and respond to it by serializing the state of the object. This state will then be sent by Pikko Server to the cell server that was entered, making sure it starts out with the exact same object. Implementing the serialization of objects is the responsibility of the cell server programmer.The Mast Model
Pikko Server uses a model similar to how cellular networks work for determining the regions handled by each cell server. In a cellular network, a mobile phone is always connected to the closest physical mast, and is automatically switched between masts when moving around. The same principle is used for cell servers. Each cell server is assigned an associated "mast" in the virtual world by Pikko Server, and players and other game objects are then handled by the server with the closest mast. When a player moves away from its current mast toward another, a handover is initiated by Pikko Server and the player is moved to the new server. The regions handled by cell servers in each zone are not static, they are continuously changed to adapt to the current situation in the zone. Pikko Server moves the masts around in the zone in order to balance the amount of players handled by each cell server. This means that handovers can happen between cell servers even when no player is moving, until equilibrium is achieved. This dynamic nature of the masts makes for a very flexible and scalable architecture that always adapts to the current gameplay. For masts to be able to move around quickly, the cell servers governing a zone need to have the entire zone loaded into memory for the duration of the game. In this way, they will be able to handle any part of the zone equally well as any other and will be able to accept players entering from anywhere. Although it would be conceivable for cell servers to only load the part of the zone that currently contains players, and dynamically load in new parts as players move around, this is not currently supported since cell servers are not aware of their locations in the virtual world.Writing a Cell Server
As mentioned previously, cell servers are normal uLink servers with a few modifications and additions to make them suitable for MMOs. It is therefore straightforward to convert an existing uLink server to a cell server. The main differences between a normal uLink server and a cell server are:- Cell servers need to support handing objects over to other cell servers. They need to provide serialization and deserialization of network objects.
- Cell servers must be authoritative.
- Manual view IDs cannot be used by cell servers.
- Initialization of cell servers is done using InitializeCellServer() instead of InitializeServer().
- Some callbacks are different for cell servers.
Initializing a Cell Server
Cell servers are initialized using the following method:NetworkConnectionError InitializeCellServer(int maxClients, string pikkoServerHost,
int remotePort)
maxClients is the maximum number of clients that can connect to the
cell server. pikkoServerHost is the host name of the computer where
Pikko Server is running, and remotePort the port Pikko Server
listens to for new cell servers. Calling this method will have the effect of
starting the cell server and connecting it to Pikko Server on
remotePort. It will then be immediately redirected to a new, unique
port which all future communication with Pikko Server will go through.
When the cell server has successfully connected to Pikko Server it gets the
callback uLink.Network.uLink_OnConnectedToPikkoServer(). The callback
uLink.Network.uLink_OnServerInitialized() is not invoked for cell servers.
Object Instantiation
Cell servers must be authoritative (see the Authoritative Server Details chapter). Among other things, this means that only cell servers, not clients, can instantiate objects over the network. Cell servers can call uLink.Network.AllocateViewID() or uLink.Network.AllocateViewIDs() to get a free view ID that can be passed to uLink.Network.Instantiate(), or use one of the uLink.Network.Instantiate() versions that automatically allocates a view ID. These are the only ways to get view IDs - manual view IDs are currently not supported by Pikko Server. Pikko Server handles the view ID allocation so that all cell servers will get unique and global view IDs across the game. Note that this will only spawn the object on the cell server that performed the instantiation. The object will be managed by Pikko Server, however, and moved seamlessly between cell servers when necessary. It will also be spawned on all clients that can see the object, not just those connected to the concerned cell server. The instantiation is buffered in the usual way, and sent to clients upon first connecting to a cell server (but not during a handover to another cell server).Handovers
When Pikko Server notices that an object is crossing over a cell server boundary it will initiate a handover. The following method will be called on the object in the cell server it is currently in:void uLink_OnHandoverNetworkView(uLink.BitStream stream,
uLink.NetworkMessageInfo info)
This method works in the same way as the uLink.Network.uLink_OnSerializeNetworkView()
method used for state synchronization. The object should serialize all important
state that will be needed in the new cell server. Note that this is usually more
state than is needed for state synchronization, since the object will be moved
completely from the old server to the new.
The object will then be deleted from the old server and recreated on the new
server. Similar to when performing a network instantiate, the
uLink.Network.uLink_OnNetworkInstantiate() callback will be called on the object on the new
server. The networkView.initialData member of the
uLink.NetworkMessageInfo argument will contain the same data as in the
original instantiation.
After this, uLink.NetworkP2P.uLink_OnHandoverNetworkView() will be called on the new
object. It is passed the stream containing the object, allowing it to
deserialize the saved state.






