Requirements
Prerequisite knowledge
Previous experience creating games on iOS using Flash Builder or Flash Professional will help you make the most of this article. Additional required other products Game Kit AIR native extension by vitapoly or Game Kit AIR native extension trial by vitapoly
Required products
Flash Builder 4.6 Standard(Download trial)
Flash Builder (Download trial)
Adobe Animate CC
Adobe AIR
Sample files
GameInput.zip (119 KB)
User level
Intermediate

Using the Game Kit AIR native extension for iOS, games built with Adobe AIR can set up real-time Game Center multiplayer matches, send and receive custom data between players, and enable voice chat during gameplay. This native extension also supports turn-based matches, as well as the leaderboard and achievements. All of these features are available via in an easy-to-use, high-level API, which is complemented by a low-level API to all native Game Kit calls in case you need advanced functionalities. The low-level API provides complete access to the native Game Kit framework with all its classes, properties, methods, delegates, and callback functions.
 
Real-time Game Center matches require a minimum of two and a maximum of four players to be connected simultaneously. Game Kit provides matchmaking functionalities to find other players along with all of the networking infrastructure to pass data between players. It also provides extensive voice chat support between players. You can implement your game on top of these capabilities without having to worry about how game or voice data is delivered to all players.
 
Although the Game Kit native extension includes the entire Game Kit framework, this article focuses only on the high-level API, to help you quickly jump into creating real-time multiplayer games. For more information on using the native extension for turn-based multiplayer games, see Creating turn-based multiplayer games on iOS with the Game Kit AIR native extension.
 

 
Setting up

To get started, you must first set up your game for Game Center on iTunes Connect, and set up your ActionScript Mobile project to use the Game Kit AIR native extension.
 
 
Setting up your game for Game Center multiplayer
Before your game can access multiplayer capabilities on iOS, you need to enable Game Center and multiplayer for your game on iTunes Connect.
 
  1. Log in to iTunes Connect at http://itunesconnect.apple.com.
  2. Click Manage Your Applications.
  3. If you are creating a new game, follow the standard procedure to do so and then go to the next step. If you are editing an existing game, select your game.
  4. Click Manage Game Center on the right (see Figure 1).
Figure 1. The Manage Game Center button on iTunes Connect.
Figure 1. The Manage Game Center button on iTunes Connect.
 
  1. Enable for Single Game. You can also select Enable for Group Games if you want this game to share Game Center features with other games. For example, if your game has a free version and a premium version, you would want players from both versions to be able to play with each other.
  2. Enable Game Center (see Figure 2).
Figure 2. Enabling Game Center for your game.
Figure 2. Enabling Game Center for your game.
 
  1. Click Done. You have now enabled Game Center for your game. However, you still need to enable Game Center and Multiplayer for the current version.
  2. Under Current Version, click View Details.
  3. Scroll down to Game Center, and enable it. Make sure this version is selected under Multiplayer Compatibility (see Figure 3).
Figure 3. Enabling Game Center and Multiplayer for a specific game version on iTunes Connect.
Figure 3. Enabling Game Center and Multiplayer for a specific game version on iTunes Connect.
 
 
Setting up your ActionScript mobile project for multiplayer
The Game Kit ANE package comes with the GameKit.ane file for use in Flash Builder and Flash Professional. The package also comes with GameKit.swc if you are using FlashDevelop.
 
 
Set up for Flash Builder 4.6 and Flash Builder 4.7
 
 
  1. In Flash Builder, choose Project > Properties.
  2. Click ActionScript Build Path on the left (see Figure 4).
Figure 4. Preparing to add GameKit.ane to a project.
Figure 4. Preparing to add GameKit.ane to a project.
 
  1. Click the Native Extensions tab.
  2. Click Add ANE, and select GameKit.ane.
  3. Click Apple iOS under ActionScript Build Packaging on the left (see Figure 5).
Figure 5. Packaging options for GameKit.ane.
Figure 5. Packaging options for GameKit.ane.
 
  1. Click the Native Extensions tab.
  2. Select the Package column for GameKit.ane.
  3. Type the iOS 6 SDK path for Apple iOS SDK. The default location on OS X is /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/.
  4. If you are using other ANE files from vitapoly, select Hide ANE-Library-Symbols to resolve build errors.
  5. Click OK.
  6. Edit your app.xml file and make sure the Application ID matches the one for your game on iTunes Connect.
  7. When debugging, be sure the AppId in the Main tab also matches. Flash Builder 4.7 automatically adds ".debug" to the end of the application ID. You will need to delete this suffix so the entire AppId field matches the one for your game on iTunes Connect. 
 
Set up for Flash Professional CS6
If you are using Flash Professional on Windows, you need to use AIR SDK 3.5 or higher because Game Kit AIR native extension requires iOS SDK 6 to build. Flash Professional on Mac OS X lets you specify the iOS SDK but on Windows it doesn't.
 
  1. In Flash Professional, choose File > ActionScript Settings.
  2. Click the Library Path tab.
Figure 6. Adding GameKit.ane to a project in Flash Professional.
Figure 6. Adding GameKit.ane to a project in Flash Professional.
 
  1. Click Browse To A Native Extension (ANE) File, and select GameKit.ane (see Figure 6).
  2. Click OK.
  3. Chose File > AIR 3.x for iOS Settings.
  4. Select iOS SDK, and type the iOS 6 SDK path for Apple iOS SDK. The default location on Mac OS X is /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/ (see Figure 7).
Figure 7. Adding iOS SDK paths to the AIR for iOS settings.
Figure 7. Adding iOS SDK paths to the AIR for iOS settings.
 
  1. Type the iOS 6 Simulator SDK path,
    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk
  2. Click OK.
  3. Edit your app.xml file and make sure the Application ID matches the one for your game on iTunes Connect.

 
Getting started with the Game Kit AIR native extension

Before using real-time Game Center match services, your game must instantiate and initialize the Game Kit native extension during launch, and before any user interface is presented. Initialization of the Game Kit native extension includes authenticating the local player, which may pop up the native Game Center authentication interface. If your game has only multiplayer mode, it should not allow the player to proceed if authentication fails. However, if your game also has single player mode, you should still authenticate as early as possible in the launch process, but just disable the multiplayer menu items if authentication fails.
 
  1. Import the necessary namespaces:
import com.vitapoly.nativeextensions.gamekit.*; import com.vitapoly.nativeextensions.gamekit.events.*; import com.vitapoly.nativeextensions.gamekit.ios.*; import com.vitapoly.nativeextensions.gamekit.realtime.*; import com.vitapoly.nativeextensions.gamekit.turnbased.*;
  1. Check if the native extension is supported on the currently running platform. The Game Kit AIR native extension is supported on iOS devices and iOS Simulator, but not on the AIR Simulator. However, some Game Center functionalities are not available on the iOS Simulator due to a limitation of the iOS Simulator.
var supported:Boolean = GameKit.isSupported;
  1. Instantiate a GameKit object or get the singleton:
var gamekit:GameKit = new GameKit();
or
 
var gamekit:GameKit = GameKit.instance;
  1. Authenticate the local player, setting up listeners for the relevant events first:
gamekit.addEventListener(GameKit.LOCAL_PLAYER_AUTHENTICATED_EVENT, function(e:Event):void { trace("LOCAL_PLAYER_AUTHENTICATED_EVENT"); }); gamekit.addEventListener(GameKit.LOCAL_PLAYER_NOT_AUTHENTICATED_EVENT, function(e:ErrorEvent):void { trace("LOCAL_PLAYER_NOT_AUTHENTICATED_EVENT: " + e.text); // don’t allow to proceed if no single player // or just disable multiplayer interface disableMultiplayer(); // implement your own }); gamekit.authenticateLocalPlayer();
  1. Your game is now initialized for Game Kit. You can get more information about the local player after a successful authentication:
var localPlayer:LocalPlayer = gamekit.localPlayer; trace(localPlayer.displayName); // load friends with a completion callback function localPlayer.loadFriends(function(friends:Array):void { // localPlayer.friends property is now loaded for each (var friend:Player in localPlayer.friends) trace("friend: " + friend.displayName); });

 
Initializing for real-time matches

The Apple Game Kit framework uses delegates and callback functions for events. The low-level API of the Game Kit ANE provides the same mechanisms. However, to adhere to ActionScript conventions, the high-level API of the Game Kit AIR native extension dispatches events.  The high-level API is designed with ease of use in mind and combines multiple low-level APIs for minimal coding.
 
The high-level API comes with the RealTimeMatchesController class, which helps you create and control real-time matches. Before you can use it, you need to first initialize it:
 
gamekit.realTimeMatchesController.init();

 
Starting a match

The Game Kit AIR native extension enables games to use the native matchmaking interface (see Figure 8) as well as the low-level API (if you want to create your own custom interface).
 
Figure 8. The native matchmaking interface.
Figure 8. The native matchmaking interface.
 
Using the native interface is straightforward. It involves listening for three events and calling one method.
 
  1. Listen for the event that is triggered when matchmaking fails. This happens when there is an error connecting to Game Center or when Game Center cannot find a match that satisfies the request, for example, when there are not enough players. You should display the error message and update your interface when this happens.
gamekit.realTimeMatchesController.addEventListener(RealTimeMatchesController.MATCH_MAKER_FAILED_EVENT, function(e:ErrorEvent):void { trace("MATCH_MAKER_FAILED_EVENT: " + e.errorID + ", " + e.text); });
  1. Listen for the event that is triggered when the player cancels the matchmaking process. You should update your interface accordingly when this happens.
gamekit.realTimeMatchesController.addEventListener(RealTimeMatchesController.MATCH_MAKER_CANCELLED_EVENT, function(e:Event):void { trace("MATCH_MAKER_CANCELLED_EVENT"); });
  1. Listen for the event that is triggered when the matchmaker finds a match for the player. The MatchEvent class contains the match that was created. RealTimeMatchesController also stores it as the currentMatch property, which holds the latest match created. If your game requires more than one real-time match at a time, which is unlikely and probably too complicated for the interface, you can save the match somewhere for use later. When this event is triggered, you should check if the match's expectedPlayerCount property is 0, which indicates that enough players have joined the match, and the game can now start.
gamekit.realTimeMatchesController.addEventListener(RealTimeMatchesController.MATCH_MAKER_FOUND_MATCH_EVENT, function(e:MatchEvent):void { trace("MATCH_MAKER_FOUND_MATCH_EVENT: " + JSON.stringify(e)); match = e.match; // save the match somewhere // or use gamekit.realTimeMatchesController.currentMatch // start game if not expecting anymore players to join if (match.expectedPlayerCount == 0) startGame(); // implement your own });
  1. After listening for all these events, bring up the native matchmaking interface with startRealTimeMatch(). The first argument is the minimum number of players that the match requires. The second argument is the maximum number of players. Matchmaker starts a game if the number of players filled for a match is between these two numbers inclusively.
// bring up native match making interface for a match with 2 to 4 players gamekit.realTimeMatchesController.startMatch(2, 4);

 
Inviting friends to a match

The native matchmaking interface enables players to invite their Game Center friends to play a real-time match. You do not need to do any work for the inviting side within your game. However, players can also invite others to play your game from within the Game Center app. In that case, the Game Center app launches your game, and the Game Kit AIR native extension dispatches an event to let you know. You need to listen for this event and show the native matchmaking interface but with the invited players filled in; for example:
 
gamekit.realTimeMatchesController.addEventListener(RealTimeMatchesController.INVITE_PLAYERS_EVENT, function(e:InvitePlayersEvent):void { trace("INVITE_PLAYERS_EVENT: " + JSON.stringify(e)); // launched from Game Center, bring up matchmaking interface with the array of invited players gamekit.realTimeMatchesController.startMatch(2, 4, 0, 0, e.playersToInvite); });
When a player receives an invitation to play your game, it comes in the form of a push notification. If the player accepts the invitation by tapping on the notification, your game is launched, and the Game Kit AIR native extension automatically brings up the matchmaking interface to start a new game and dispatches an event. You will need to listen for this event as well.  When it is received, clean up any current game appropriately and get ready for the new game; for example:
 
gamekit.realTimeMatchesController.addEventListener(RealTimeMatchesController.INVITE_ACCEPTED_EVENT, function(e:Event):void { trace("INVITE_ACCEPTED_EVENT: " + JSON.stringify(e)); // accepted an invite from another player, clean up current game and show new game });
You need to add the two above event listeners before you call gamekit.realTimeMatchesController.init(), because they can be dispatched during initialization.
 

 
Exchanging data between players

Once the matchmaker hands you back a match and the match is started, your game needs to exchange data between the players so the state of the game is synchronized among all players. With the Game Kit AIR native extension your game can send data to all players or  selected players, and can send the data reliably or unreliably. Sending it reliably guarantees the data will reach its destination and in the same order that you sent it, but it may be slower because it needs to make sure all data is acknowledged or retransmitted. Sending it unreliably sends it only once, and you will not know if the data reached the other player. However, if you are sending real-time information continuously, sending unreliably is suitable. The data you are sending is a ByteArray. You can encode or serialize the data however you want, as long as you decode it the same way on the receiving end. Careful design using binary encoding of your game's data structures is preferred, but JSON or strings are perfectly good approaches when starting out.
 
 
Sending data
To send data to other players, use the RealTimeMatch object's sendData() and sendDataToAll() methods. The last argument indicates whether to send the data reliably.
 
var data:ByteArray = new ByteArray(); data.writeUTFBytes("hello"); // send data to all players reliably match.sendDataToAll(data, true); // send data to the match's first player unreliably match.sendData(match.players[0], data, false);
 
Receiving data
Data received from other players are dispatched through an event. When the match starts, you can listen for this event and process the data in the callback function.
 
match.addEventListener(RealTimeMatch.RECEIVED_DATA_EVENT, function(e:DataReceivedEvent):void { trace("RealTimeMatch.RECEIVED_DATA_EVENT from " + e.player.playerID + ": " + e.data.toString()); processData(e.data); });

 
Voice chats

One of Game Kit’s best features is voice chat support for real-time multiplayer matches. You don’t need to worry about capturing audio from the microphone, encoding and sending the voice data, or mixing and playing audio to the speaker. All of that is taken care for you. You just need to specify which players join which channels, and which players want to talk.
 
A real-time match can have multiple channels and each player can join more than one channel at a time. For example, you can have one channel for all players in the match, another channel for blue team players, and one more channel for red team players. Once two players join the same channel, they will be automatically connected in a voice chat. Each player then needs to explicitly opt to talk before Game Kit starts capturing and sending audio. Each player can only talk in one channel at a time,  even if the player has joined multiple channels.
 
var chat:VoiceChat = match.getVoiceChat("all"); // join the voice chat so this player can hear other players chat.join(); // set talk to true so other players can hear this player chat.talk = true; // leave a chat some time later chat.leave();

 
Cleaning up a match

When a real-time match ends, which is determined by your game logic, you need to disconnect and clean it up properly using the disconnect() method. When you invoke it, disconnect() also disconnects all voice chats. To clean up the native objects, you then need to call dispose(). If you kept the match as a variable somewhere before, you would also need to set that variable to null so the garbage collecter can do its job. Even if you did not keep the match, you still need to call disconnect() and dispose() on gamekit.realTimeMatchesController.currentMatch.
 
match.disconnect(); match.dispose(); // releases the native match object match = null;

 
Where to go from here

You can now use the Flash platform combined with the simple but powerful Game Kit AIR Native Extension to create real-time Game Center multiplayer games. A trial version of the Game Kit AIR native extension is available here. For API details, refer to the Game Kit API documentation.
 
The namespaces com.vitapoly.nativeextensions.gamekit and com.vitapoly.nativeextensions.gamekit.realtime contain the high-level API. The low-level API, which includes the complete iOS Game Kit framework is in the namespace com.vitapoly.nativeextensions.gamekit.ios.
 
We can’t wait to see your next multiplayer big hit!