Flock Basics


  1. About, Events
  2. Server & Testserver
  3. Matchmaking
  4. Security & Performance
  5. Anonymous & Authenticated Sessions
  6. User Authentication & Registration
  7. User Attributes & Data Storage
  8. Participant Objects of a Session
  9. FlockActivity
  10. Statistics
  11. Facebook API

About

Flock is an event-driven multiplayer engine which connects to a fast, redundant server infrastructure hosted across various Amazon datacenters. This document covers the basics and underlying concepts for developers new to the framework. You can help us improving it by providing feedback, questions and ideas via mail to support@flockengine.com.

This is an overview of the general architecture:

Commonly Used Terms

LobbyWaiting room until enough participants with the same settings are found (groups and maxPlayersPerGame). After FlockEvent.CONNECTION_ESTABLISHED, before .SESSION_STARTS.
SessionAn active game after waiting in the lobby. Multiple participants exchange messages. After FlockEvent.SESSION_STARTS
ParticipantA player inside a session. Accessible via Flock.getAllParticipants(), which returns an array of Participant objects.


Connecting

The following steps are required in order to connect clients to a session:
  1. Set an event-listener to receive callbacks from the engine
  2. To use the testserver, set Flock.setTestServer(true)
  3. Decide whether you want anonymous or authenticated sessions (info).
    1. If anonymous: set Flock.setAnonymousSession(true) and an username with Flock.User.setUsername(String username).
    2. If authenticated: Create an account with Flock.User.createAccount() or authenticate with Flock.User.authenticate() or Flock.User.authenticateWithFacebook()
  4. Call Flock.connect(String groups, int players_per_game). All clients with same group and max-players qualify to be matched for a session (see matchmaking).

The socket connection is handled by a background service, which allows you to connect different Activities to the same socket connection. Useful for starting a second Activity when the session starts (in-game screen). Have a look at the examples to see it in action.


Events

The last Activity which set an event-listener receives notifications about status changes, such as CONNECTION_ESTABLISHED, SESSION_STARTS or NEW_MESSAGE (full list). These events include the sender-id (-1 for the server, 0..n for other participants) and possibly a message-string (the sender-id matches the array index of Flock.getAllParticipants()).

There are two basic ways of creating the listener:

  1. Have the Activity implement FlockEngine.FlockEventCallback and using Flock.setOnEventListener(this)
    public class YourActivity extends FlockActivity implements FlockEventCallback {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Flock.setOnEventListener(this);
        }
        
        public void onFlockEvent(FlockEvent event, int sender_id, String msg) {
            Log.v("", "new event: " + event + ", sender=" + sender_id + ", msg=" + msg);
        
            switch (event) {
            case SESSION_STARTS:
                Toast.makeText(this, "Game Starts", Toast.LENGTH_SHORT).show();;
                startActivity(new Intent(YourActivity.this, Game.class));
                break;
            }
        }
    }
    
  2. Manually creating the listener without implements:
    Flock.setOnEventListener(new FlockEventCallback() {
        public void onFlockEvent(FlockEvent arg0, int arg1, String arg2) {
        }
    });
    
For further information have a look at the examples, and you can see all possible events in the enum FlockEvent. This is the example of an event-flow:
   Activity                FlockEngine           Server        
       |                        |                  ||
       |        connect()       |                  ||
       |----------------------->|                  ||
       |                        |<---------------->||
       | CONNECTION_ESTABLISHED |                  ||
       |<-----------------------|                  ||
       |                        |                  ||
       |                        |                  ||
       |                        |                  ||              Opponent
       |                        |                  ||                 |
       |     SESSION_STARTS     |<-----------------||---------------->|
       |<-----------------------|                  ||                 |
       |                        |                  ||                 | 
       |                        |                  ||<----------------| Opponent sends message
       |      NEW_MESSAGE       |<-----------------||                 |
       |<-----------------------|                  ||                 |
       |                        |                  ||                 |
       |  sendMessage(String)   |                  ||                 |
       |----------------------->|                  ||                 |
       |                        |----------------->||   NEW_MESSAGE   |
       |                        |                  ||---------------->|
       |                        |                  ||                 | 
       |                        |                  ||                 | 
       |                        |                  ||<-------X--------| Opponent quits Activity
       |   PARTICIPANT_QUIT     |<-----------------||                 |
       |<-----------------------|                  ||                 |


Server & Testserver

Testservers are available for immediate testing of the engine. The testserver accepts anonymous as well as identified sessions, and behaves exactly as a regular server with a few exceptions:

For your Activity to use the testservers, simply set Flock.setTestServer(true) in all Activities dealing with Flock (authenticating and connecting, but also in-game and highscore Activity). Changing to a private gameserver later on is hassle-free: set it up via the web interface and remove setTestServer().


Matchmaking

Matchmaking is the process of matching the best opponents which wait in the lobby for a new game. Developers can specify multiple groups when calling Flock.connect(groups, maxPlayersPerGame). The parameter groups is a colon separated list of group-names (eg. "beginners,experts").

If in one of the requested groups enough players were found, a new game starts and the players are removed from the lobby. At receiving FlockEvent.SESSION_STARTS, the callback parameter msg is the group in which the players were found.


Security & Performance

Flock implements SSL/TLS and AES-256 encryption methods to provide full confidentiality of all user-related information. Connecting to a gameserver always initiates a sequence of connections. The first is always encrypted with SSL/TLS, authenticates the user for the first time and receives ip and port of the target instance. Developers can choose between using SSL/TLS connections for the subsequent game-connection (including in-session messages), or only to encrypt authentication tokens with AES and to transfer the messages in plain text.

Encrypting the messages requires additional cpu processing time at the clients and reduces the maximum throughput, and many games want faster exchanges than possible over a SSL tunnel. In this case you can disable encryption for in-session messages remotely via the web interface the clients automatically adjust to it.


Pings and Delays

Our first measurements resulted in an average relay-time for messages from one participant to all other participants of 0.02 secods for ethernet/wifi networks, and up to 0.2 seconds for clients using 3G networks. More comprehensive benchmarks coming soon!


Anonymous & Authenticated Sessions

You can choose to use anonymous as well as authenticated sessions. Default is authenticated, to enable anonymous sessions use Flock.setAnonymousSession(true). Here is an overview of the differences:

Anonymous

Authenticated


User Authentication & Registration

Only required for authenticated sessions.

Each user is identified by a unique username and a password, which is verified with the user-database. Authentication and registration is done in a Thread in the background; the responses are received via the onFlockEvent callback (see Events). Developers can use the same user database across multiple games.

User-accounts can be created by using Flock.User.createAccount() or Flock.User.createAccountWithGui(). If an account is succefully registered, the user is also authenticated. The status-events after creating an account can be:

  1. CREATEACCOUNT_SUCCESS ........ Account successfully created (always followed by AUTH_SUCCESS)
  2. AUTH_SUCCESS ................. User authentication successful
  3. CREATEACCOUNT_FAILED ......... Network problem
  4. CREATEACCOUNT_USERNAMETAKEN .. Username already taken

Signing into an existing account can be done with Flock.User.authenticate() or Flock.User.authenticateWithGui(). Possible status events:

  1. AUTH_SUCCESS ......... User authentication successful
  2. AUTH_FAILED .......... Technical problem on server side
  3. AUTH_REJECTED ........ Username/Password combination invalid

Have a look at the example "Dice Full" inside the SDK, where you can see it in action!


User Attributes & Data Storage

For authenticated users Flock provides a persistent key-value storage system for up to 250 attributes for every user for every game (since a user-database can be used for multiple games). The attributes are saved to a global, redundant database and can automatically be requested for all participants when the game starts (useful to "auto-load" common attributes such as "points" and "level" for every participant of a game).

The attributes are key-value mappings with Strings and Numbers. You can save attributes for the user to the global databse with the UserAttributeSyncer. Possible responses via status events:

  1. FlockEvent.ATTRIBUTEUPDATE_SUCCESS
  2. FlockEvent.ATTRIBUTEUPDATE_FAILED

If one of the participant updates it's attributes, all other participants receive FlockEvent.NEW_ATTRIBUTE. As always the sender_id of the event maps to the array-index of Flock.getAllParticipants()

To automatically load certain attributes for all participants joining a session, request them with requestUserAttributeNumber(String, long) or requestUserAttributeString(String, String) calling Flock.connect().

See also the example "Dice Full".

Accessing user attributes outside a game

Since version 0.3.0 you can retrieve the local users attributes outside a game with Flock.User.retrieveAttributes():

Flock.User.retrieveAttributes(new UserAttributesCallback() {
    public void onAttributesReceived(Map attributes) {
        if (attributes.isEmpty()) {
            log("Empty attributes map");
        } else {
            Iterator i = attributes.entrySet().iterator();
            Map.Entry me;
            while (i.hasNext()) {
                me = (Map.Entry) i.next();
                log("Attribute '" + me.getKey() + "': " + me.getValue());
            }
        }
    }
});


Participant Objects of a Session

The Participant object is a simple representation of every player within a session. You can retrieve an array with all participants of this session with Flock.getAllParticipants() after receiving FlockEvent.SESSION_STARTS. This array also includes participants which have already quit, in order to keep the array index mapped to the sender-id of events.

Important methods of the Participant object:

                 String Participant.getUsername()
                    int Participant.getUserId() // 0..n
                boolean Participant.isActive()  // false if user has quit
                 String Participant.getAttributeNumber(String key, long defValue)
                 String Participant.getAttributeString(String key, String defValue)
HashMap<String, String> Participant.getAttributes()
You can retrieve the Participant object of the local user with Flock.getLocalParticipant(). See also Participant in the API Reference.


FlockActivity

FlockActivity is a helper class with the aim to simplify using the engine. It is just a normal Activity which additionally instantiates FlockEngine as this.Flock, unbinds the background service at onDestroy, and notifys the client activity as soon as the connection to the service is established.

Read more: FlockActivity


Statistics

Developers have access to web-based visualizations of the status of the gameserver instances, the history of logins and games played and many other things. All statistics can be grained down to an hourly overview and details about any single player. Furthermore you can choose to receive daily reports by mail, including all informations and statistics about the activity of your application.


Facebook API

To use the Facebook API you need to register your app at facebook and supply your app id to Flock.User.authenticateWithFacebook(String app-id). After the user signed in with Facebook, you can access the API via the class Flock.User.Facebook.

You can register your app here: http://developers.facebook.com/setup/ (be sure to format your url like this: http://flockengine.com/ (no www., with trailing slash))

See also:


If you have questions or feedback please send us a mail to support@flockengine.com.