• Examples (iOS)
• Examples (Android)
• Examples (C++)
Server API Documentation

 

Since 2.8.0

» Advanced uses of the MMORoom and MMO API

This article requires that you are already familiar with the MMORoom features introduced in SmartFoxServer 2X version 2.8. Here we expand on some of the advanced techniques that can be used from the server side. If you are not familiar with MMORooms and the MMO API, please make sure to read the MMORoom Overview here.

» Custom Area of Interest (AoI)

One advanced aspect of the server-side MMO API is the ability to use a custom AoI that is smaller or equal than the one configured in the MMORoom. This feature allows to restrict the area of the map in which a specific event is broadcast.

Let's take a look at this simple 2D map diagram:

The green circle is our player and the orange area represents the AoI, so all events generated by the player will be transmitted to the other clients falling within that proximity range (orange circles). From the Extension code we can also broadcast events and messages that affect a smaller area: in this case the cyan rectangle represents a smaller AoI that can be defined at runtime.

» Intended use

The applications of a custom AoI can be different, such as sending a public message only to Users that are in a shorter range, or triggering events in areas within the main AoI, e.g. an explosion that will only affect players closer to the source of the event.

The server side SFSMMOApi class (under the com.smartfoxserver.v2.api package) exposes a couple of useful methods to do this:

Instead of taking a list of recipients as the "regular API", here we must provide a Vec3D representing the AoI around the sender. As we have already mentioned the custom AoI must be <= default AoI.

Q: Why can't we define a custom AoI of any size, e.g. larger that the Room's default AoI

The MMORoom uses a highly optimized internal data structure to keep all lookup operations very fast and efficient, even with thousands of Users and MMOItems interacting at the same time. In order to do this the data structure uses the default AoI as the main unit of storage and can only allow searches within those units.

If you need to select a more complex group of Users based on multiple areas of the MMORoom you can still do it manually, we'll show exactly how in the next few paragraphs.

» Extending the MMOItem Class

We have seen in the MMORoom Overview article how MMOItems can be used to represent all sorts of interactive objects: triggers, bonuses, projectiles etc... We are now going to show a practical example by defining two specific entities that we will use in our hypothetical game: switches and doors.

We want our MMORoom to have a number of secret passages that can be opened at a distance via several switches located in the map. When the switch is activated a nearby secret door will open and we will trigger this event to the clients to show an animation of the door opening (or closing).

In order to describe these objects on the server side we will extend the MMOItem class and add the extra bits of information that are required:

public class SwitchItem extends MMOItem
{
	private boolean state;
	
	public DoorItem(boolean state)
	{
    	super();
		this.state = state;
	}
	
	public boolean getState()
	{
		return state;
	}
}


public class DoorItem extends MMOItem
{
	private Vec3D location;
	private SwitchItem relatedSwitch;
	
	public DoorItem(Vec3D location, SwitchItem relatedSwitch)
	{
    	super();
		this.location = location;
		this.relatedSwitch = relatedSwitch;
	}
	
	public Vec3D getLocation()
	{
		return location;
	}
	
	public boolean isOpen()
	{
		return relatedSwitch.getState();
	}
}

Our SwitchItem has adds an extra boolean representing its state, while the DoorItem has a Vec3D representing its position on the map and a reference to the related SwitchItem that opens/closes the passage.

» Extension messages

Now that we have defined the two game items let's see how we can trigger an event from Extension code only to those users falling within the door's AoI.

public void handleSecretDoorStateChange(DoorItem secretPassage)
{
	SFSObject msg = new SFSObject();
	
	// we add the Id of the passage to be opened/closed
	msg.putInt("itemId", secretPassage.getId());
	
	// we add the status of the secret passage
	msg.putBool("open", secretPassage.isOpen());
	
	// Obtain the list of Users within the item's AOI
	List<User> recipients = getParentRoom().getProximityList(secretPassage.getLocation());
	
	// Send event to selected clients
	send("handleDoor", msg, recipients);
}

The "trick" here is to use the MMORoom's methods to obtain what we need. In this case we're asking a list of Users that fall within the default AoI given certain coordinates. The MMORoom object provides several useful methods for these tasks:

Now let's suppose our game also supports floor trap doors. The player who discovers the hidden switch to the trap door can wait until one or more unwary Users step on the right spot, and then activate the door to capture them.

In this case the event should only be propagated to the Users that are in a smaller area of the Room: just those whose position is within the trap door perimeter. We can accomplish this task by employing a custom AoI and calling the last method in the previous list.

» Advanced tricks

As we have mentioned, we can perform searches inside the Room by using a custom AoI provided that it's size is less than or equal to the default AoI. This should cover 95% of the cases, but what about the remaining few situations?

For the sake of this example we will have a player generating an event that should be received by more User outside the default AoI. Let's suppose our RPG hero has just cast an earthquake spell, the effects of which must propagate to a much larger area than the default AoI.

In order to accomplish this task we can simply perform multiple User lookups in adjacent areas (AoI), aggregate the results in a single List and finally use with it with the usual send(...) Extension method. In other words we can employ the default AoI as a unit of subdivision of the virtual map and perform multiple searches by moving the target coordinates by one or more units.

By default the MMORoom will only search within the limits of 1 unit, but from server code we're free to aggregate multiple searches and even cherry pick specific players from the full MMORoom's user list, thus allowing high flexibility to filter the recipients of a specific server message or event.