Examples (iOS)
Examples (Android)

 

» The Game API

SmartFoxServer 2X provides a new set of client and server API specifically designed for game creation and management, including public and private games, game invitations, User and Room matching and lots more. The new Game API are based on three fundamental building blocks:

These three components are highly versatile and can be either used singularly for a specific task or orchestrated together to create advanced server behaviors, as you will learn in a few seconds.

» Overview

The SmartFoxServer class exposes a getAPIManager() method which in turn allows you to access all the different API subsets in the SFS2X framework. The APIManager provides:

We will now concentrate on the Game API.

» Match Expressions

Match Expressions are built like "if" conditions in any common programming language: they work like queries in a database. Here's a Java example to get you started:

 
MatchExpression exp = new MatchExpression('rank', NumberMatch.GREATER_THAN, 5).and('country', StringMatch.EQUALS, 'Italy')

Expressions are made of three elements:

Additionally any number of expressions can be linked together with a logical AND / OR operator, just like in regular code. In the above example we have created an expression that will check for a rank value > 5 and a country value == "Italy".

But... where is this set of conditions applied to? Normally expressions are used to match Users (via their User Variables) and Rooms (via their Room Variables). The standard SFS2X API provide two useful methods called findUsers() and findRooms() where you can execute any Match Expression and obtain the filtered set of Users/Rooms.

A small example will clarify this better:

 
List<User> matchingUsers = sfsApi.findUsers(zone.getUserList(), exp, 50);

The first argument provides a list of User objects where to search, in this case all Users inside the current Zone. The second parameter is the Match Expression we just created at the beginning of this section, and the last number (50) is an optional limit for the amount of returned elements. In this case we want the search for no more than 50 matching elements (if we passed 0 the search would return all Users that match).

The search options are not just limited to User/Room Variables name. In fact the Matching engine provides two extra classes, RoomProperties and UserProperties, where you can access many specific attributes of the Room and User classes.

This is an example of matching specific Room properties and Variables:

 
// Prepare match expression
MatchExpression exp = new MatchExpression(RoomProperties.IS_GAME, BoolMatch.EQUALS, true).and
					(RoomProperties.HAS_FREE_PLAYER_SLOTS, BoolMatch.EQUALS, true).and
					("isGameStarted", BoolMatch.EQUALS, false);
 
// Search Rooms
List<Rooms> joinableRooms = sfsApi.findRooms(zone.getRoomListFromGroup("chess"), exp, 0);

The above code will match all game Rooms that have at least one free player slot and where the isStarted variable is set to false. Additionally the search will be performed only in the Room Group called "chess".

» Advanced features

The Match Expressions offer advanced capabilities for searching through nested data structures such as SFSObject and SFSArray. This is done via a very simple dot-syntax expressions. Here's an example of how it works:

 
MatchExpression exp = new MatchExpression("europe.italy.capital", StringMatch.EQUALS, "Rome")

The above example goes down deep into an SFSObject called europe, taking the italy object (another SFSObject) and finally reading its String field capital and matching it with another String. Here is one more examples using SFSObject and SFSArray:

 
MatchExpression exp = new MatchExpression("europe.italy.majorCities.3.name", StringMatch.EQUALS, "Milan")

From the italy object we obtain a majorCities SFSArray and we grab the third item in it (the .3 expression means 'give me the element at index == 3'). The item is again an SFSObject whose name property we finally compare to a String.

The power of Match Expression doesn't end here. You can run multiple passes of matching if you need complex searches to be performed. For example you can run a first match and obtain a list of filtered Rooms and then use it to apply another expression to further refine your search, and so on and so forth.
Also you will learn more interesting usages of Match Expressions in conjunction with the SFSGame class later in this very article.

For more details on Match Expression we recommend to consult the javadoc, under the com.smartfoxserver.v2.entities.match package.

» Invitations

The invitation system included in SmartFoxServer 2X provides a generic framework for sending invitations to one ore more connected users and easily manage their responses and the expiry of the invitation itself. Invitations can be used to challenge players in a game, invite buddies to the user's place, ask permissions for specific tasks such as adding the invited user in the Buddy List, etc.

Creating an invitation is very simple, as four basic parameters are needed:

The invited User will receive the invitation and will be able to reply within the specified amount of time. A simple ACCEPT or REFUSE code is all it takes to reply plus an optional SFSObject with response parameters, if needed. In case no response is sent to the server within the expected number of seconds, the invitation will be considered as "refused".

public class GameInvitation extends SFSExtension
{
	private ISFSGameApi gameAPI;
			
	@Override
	public void init()
	{
	    gameAPI = SmartFoxServer.getInstance().getAPIManager().getGameApi();
	}
	
	public void sendInvitation()
	{
		// Prepare Invitation object
		User inviter = getParentZone().getUserByName("Fozzie");
		User invitee = getParentZone().getUserByName("Gonzo");
		
		// We set the timeout for a reply to 50 seconds 
		Invitation invitation = new SFSInvitation(inviter, invitee, 50);
		
		// Send the invitation 
		gameAPI.sendInvitation(invitation, new InvitationCallback()
		{
			@Override
			public void onRefused(Invitation invObj, ISFSObject params)
			{
				// Handle the refused invitation
			}
			
			@Override
			public void onExpired(Invitation invObj)
			{
				// Handle the expired invitation
			}
			
			@Override
			public void onAccepted(Invitation invObj, ISFSObject params)
			{
				// Handle the accepted invitation
			}
		});
	}
}

For more details about Invitations check the javadoc, specifically the SFSGameAPI class and the com.smartfoxserver.v2.entities.invitation package. Additional informations are also available in the client side API documentation.

» SFSGame

The SFSGame class extends the normal capabilities of a Room, adding the ability to set the Game as public or private and providing a list of invited people that the system will invite in the game. Additionally the system will be able to invite more people if the number of players is not sufficient to start the game.

Each game can be configured to match specific types of Users by providing a Match Expression. The expression contains criteria that are checked against each User that wants to join the game and provides a mean for filtering players.

Let's see an example: user Kermit has the following two User Variables set:

He wants to play, so he chooses a public SFSGame and attempts to join it. Unfortunately the SFSGame expression is set as follows: (Rank > 10) OR (BestScore > 3000)
Any attempt to join the Game will be refused because the player doesn't match the SFSGame criteria.

Creating a Room of type SFSGame is similar to creating a normal Room. On the client side you will find the CreateRoomRequest class and the CreateSFSGameRequest class, both taking a settings object: specifically RoomSettings and SFSGameSettings.

The following is a quick overview of the additional parameters that an SFSGame can take, compared to a regular Room:

Finally it is important to note that the SFSGame class extends SFSRoom and can be treated as any other Room in the system. SFSGame objects can be used and passed around to any method or function that works with the base Room interface (this is valid for both server and client side).

» Quick game join

Another feature offered by the Game API (both client and server side) is the QuickJoinGame request. By providing a Match Expression and a list of Rooms (of type SFSGame) or a Room Group the system can search for matching Rooms and immediately teleport the player in the game action.

As usual an example will clarify the concept:

 
// Prepare a match expresison
var expr:MatchExpression = new MatchExpression("rank", NumberMatch.GREATER_THAN, 3).and("rank", NumberMatch.LESS_THAN, 8)
 
// An array of Room Groups where we want the search to take place
var whereToSearch:Array = ["poker", "blackJack"]
 
// Fire the request and jump into the game!
sfs.send( new QuickJoinGameRequest(expr, whereToSearch) )

The above client ActionScript 3 code attempts to quickly join the user in any game from the poker or blackJack Room Groups where the game rank variable is greater than 3 and less than 8. Behind the scenes the system will also make sure that the Rooms are of type SFSGame and that there is at least one player slot available. If no Room matching these criteria is found a join error will be fired back at the user.

IMPORTANT
The QuickJoinGame feature works exclusively with Rooms of type SFSGame, which support a Match Expression; all other Room types will be ignored.