mmo-Interest-management

Introduction

MMO games are games where simultaneously large number of players are present together. A common issue with such games is that if not properly designed, they can fail under load. Suppose there are 1000 players in the MMO game and each of them can potentially interact with the other. So each player will need to receive update notifications from all other 999 players. This is going to not only create too much load on the network and the server, but also processing so many messages on the client will be unmanageable. Hence it’s important to design MMOs such that clients only receive relevant messages i.e. messages from clients that they are currently interested in.

Space War Fare

We created a sample game called Space War Fare MMO Interest management to illustrate how you can use AppWarp S2 to achieve such a design. The sample with source code (server side as well as AS3 client side) is available in the samples section of our download page.

To try out the sample, you need to first run the MMO server sample application. This is similar to how you run the basic chat server sample explained in the getting started page. You then need to make the following changes in the file Connecter.as.
public static var APIKEY:String = "49130234-abf8-402b-b"; // Replace with your AppKey from Admin Dashboard.
public static var HOST:String = "127.0.0.1"; // Address of your AppWarp S2 server
public static var ROOMID:String = "91586126"; // Room ID created from Admin Dashboard.

The core of it is Interest Area. An Interest Area is a hypothetical region which defines the surrounding near player, that is visible to the player. Anything outside this area will not hold any importance to the player. The player will be receiving messages only from the players that fall inside his interest area.

Space War Fare Sample

In the above image, the red area is the interest area for the soldier standing in it’s center. He will only receive updates only for the objects and player that are present in his interest area.

As the player moves, his interest area will also move along with it. Calculating interest area and which players and objects fall inside is very resource intensive. And doing the same for all other players can surely decrease your server’s performance. Hence, the world is divided into smaller regions. And we use interest area to know what are the regions that we need to listen for further updates. As the player moves inside the world along with its interest area, we will need to only calculate the new regions that it will be interested in. So, if any activity happens in any of these regions, we will get an update for it.

MMO interest management Screen

In the above visualization, the dots are players and red colored boundaries around it defines his interest area. Two different players can have interest area of different size. This could help players with special powers (eg: sniper lens) have a bigger interest area. Each region will contain a list of players that will be listening to it. Whenever a player moves and based on his movement, new interested regions are calculated, the player will be added to those regions list. And when the player moves, the region where he is currently in, will send the update regarding movement to all the players who are listening that region.

Server Side Logic

To implement this sample, we created following classes

  • Player
  • Region
  • World

and few helping classes

  • Rect
  • VectorI
  • VectorF

All these classes are present inside MMO package.

The object of World is created in SpaceRoom room adapter.

        private World world;
    public SpaceRoom(IRoom room) {
        m_room = room;
        world = new World(m_room, new VectorF(0,0), new VectorF(800,480),new VectorI(10,10));
    }
    

The first parameter of construct is the reference to current room where the world is being created, second and third parameter defines the origin and size of world area. Both are vector of floating values. The third parameter is the number of regions the world has to be divided into. VectorI(10,10) represents 10 regions horizontally and 10 regions vertically i.e. a total of 100 regions are present in the world.

Now, when ever a user joins the room, we also need to add him to the world. The world class has addPlayer method to add the player to the room.

Player p = new Player(sender,x,y);
p.setInterestAreaSize(new VectorF(160,96));
world.addPlayer(p);

Here we created a new object of Player class. The constructor is taking the reference of IUser and x and y of initial position of player in the world. Next, we set the interest area of Player. The parameter has to be a 2d floating vector representing the width and height of area. Lastly, we added the player to the world.

Similarly, we need to update the player, whenever a player move in the world.

Player p = world.getPlayer(sender);
p.setPosition((float)x, (float)y);
world.updatePlayer(p, removedForPlayers, removedPlayers, addedPlayers);

Here we used the getPlayer method to get the player using the IUser reference of sender. Then after updating the player’s position we simply updated the world. The updatePlayer method updates the player’s position in world and recalculate the interest area based on new position of player and recalculates what are the regions that are falling inside his interest area. This method subscribes the player to all the interested regions so that the player can listen to all the activities happening in those regions .The updatePlayer method is taking 4 parameters. The fist one is the reference to the player being updated. Other three parameters are as follows:

removedForPlayer – When the player moves, he might also exit from the interest area of other players. This List contains those players for whom the player has moved outside from there interested regions.

removedPlayers – When the player is moving, his area of interest is also moving with the him. Some players might no longer be inside his interest area. This list contains those players.

addedPlayers – Similarly like removedPlayers, some new players might have started to fall inside his interest area. This list contains those players.

Once, the player is updated, we need to send this information to all the relevant players.

world.multicastMessage(p, message);

Here we are multicasting the string ‘message` to the region where Player P is present. The world find outs the current region of Player p and send the message to all the players that are subscribed to that region.

One important step is to remove a player from world, once he leaves the room. If not done, other player will still see him even when he actually does not exists in that world.

@Override
public void onUserLeaveRequest(IUser user){
    Player p = world.getPlayer(user);
    world.removePlayer(p);
}

Client Side Logic

Our logic regarding MMO is purely server side. You don’t need anything extra on client side other the AppWarp Client SDK. All the messages are sent in form of chat messages from client. On client side you need to parse those messages and perform the actions.

Conclusion

This is how we developed MMO game that uses interest management. Since AppWarp S2 gives you complete freedom to implement any logic that you want on server side, you can easily modify or extend this interest management logic to create and implement your own logic for handling events specifically for your MMO game.

You can now read further details about our MMO sample code here