SFS2X Docs / AdvancedTopics / game-api
» 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:
- Match Expressions: they allow to create search criteria in a very natural way which can then be passed to the MatchingEngine to perform any type of queries on Rooms and Users
- Invitations: this is a generic Invitation system that allows you to manage multiple invitations to private games but it can also be employed for many other activities.
- SFSGame class: the SFSGame is new type of Room specifically designed for managing games and providing unique services for advanced game management
The easiest way to introduce the new Game API is by briefly presenting each of the components in the framework.
Just as a reminder, the SmartFoxServer class exposes a getAPIManager() method which in turn allows you to access all the different API in the SFS2X framework.
- getSFSApi(): the basic SFS2X API
- getBuddyApi(): the Buddy/BuddyList API
- getGameApi(): the Game API
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:
- Variable name
- Match operator
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 MatchExpression 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 Users where to search, in this case all Users inside the current Zone. The second parameter is the expression we just created at the beginning of the article, 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 serach 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 class.
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 expression 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
The invitation system included in SFS2X provides a generic framework for sending invitations to one ore more connected User(s) 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 task such as adding the invited User in the Buddy List etc...
Creating an invitation is very simple, four basic parameters are needed:
- Inviter: the User starting the invitation
- Invitee: the invited User/Player/Buddy
- Expiry time: the amount of seconds allowed for the invitee to reply
- Custom parameters: a generic SFSObject contatining specific invitation parameters (a message, a picture, game details...)
Invited Users can reply to the invitation with
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".
For more details about Invitations check the javadoc, specfically the SFSGameAPI class and the com.smartfoxserver.v2.entities.invitation package.
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 two variables set.
- Rank: 10
- BestScore: 2500
Any attempt to join the Game will be refused because the player doesn't match the SFSGame criteria.
Creating an SFSGame Room 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:
- isGamePublic: a public game can be joined by any Player whose variables match the SFSGame Player Match Expression. If no expression is used the game will be joinable by any User. Private games, instead, are based on invitations provided by the Game creator (see invitedPlayers below) so they usually don't need to specify any match expressions.
- minPlayersToStartGame: the minimum number of players to start the game. If the game is already running and the number of players goes below this limit the game will be stopped.
- invitedPlayers: (private games only) a list of players invited in the Game. Each player will receive an invitation event and will be able to reply within the amount of time (see invitationExpiryTime below)
searchableRooms: (private games only) a list of Rooms where the Game API can search for more players to invite. The API
will look for more players if the number of people invited is smaller than the minPlayersToStartGame. This way you can add your
friends to the game and let the system find more players to start it. This mechanism will work only when the game is started, not every time the number of Users goes below the minimum value.
If you need to search and invite more players every time the game stops you can easily do it via the SFSApi.findUsers() method.
- leaveLastJoinedRoom: auto-remove players from their previous Room after successful join
- playerMatchExpression: an expression to match players willing to play the game, by default no expression is used
- spectatorMatchExpression: an expression to match spectators willing to play the game, by default no expression is used
- invitationExpiryTime: the amount of time allowed for invited players to accept / refuse
- invitationParams: optional custom invitation parameters.These could provide details about the inviter, the game, an invitation message etc...
notifyGameStartedViaRoomVariable: automatically update a reserved Room Variable to signal that the game is started/stopped. The Room variable
uses the global setting to be broadcast outside of the Room. This can be used on the client side to show the game state in your game list.
The reserved Room Variables are found in the com.smartfoxserver.v2.entities.variables.ReservedRoomVariables class.
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 Join GamesAnother feature offered by the Game API (both client and server side) is the QuickJoinGame feature. By providing a MatchExpression 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 code attempts to quick join the User in any game from the poker or blackJack Room Groups where the Game rank variable is > 3 and < 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.
the QuickJoinGame feature works exclusively with Rooms of type SFSGame which support a MatchExpression, all other Rooms types will be ignored.