

# Add FlexMatch to a game client
Add FlexMatch to a game client

This topic describes how to add FlexMatch matchmaking functionality to your client-side game components.

We highly recommend that your game client make matchmaking requests through a backend game service. By using this trusted source for your communication with the Amazon GameLift Servers service, you can more easily protect against hacking attempts and fake player data. If your game has a session directory service, this is a good option for handling matchmaking requests. Using a backend game service for all calls to the Amazon GameLift Servers service is a best practice when using FlexMatch with Amazon GameLift Servers hosting and as a standalone service.

Client-side updates are required whether you're using FlexMatch with Amazon GameLift Servers managed hosting or as a standalone service with another hosting solution. Using the service API for Amazon GameLift Servers, which is part of the AWS SDK, add the following functionality:
+ Request matchmaking for one or multiple players (required). Depending on your matchmaking rule set, this request might require certain player-specific data, including player attributes and latency.
+ Track the status of a matchmaking request (required). In general, this task requires setting up event notification.
+ Request player acceptance for a proposed match (optional). This feature requires additional interaction with a player to display match details and allow them to accept or reject the match.
+ Get game session connection information and join the game (required). After a game session has been started for the new match, retrieve connection information for the game session and use it to connect to the game session.

## Prerequisite client-side tasks


Before you can add client-side functionality to your game, you need to do these tasks:
+ **Add the AWS SDK to your backend service.** Your backend service uses functionality in the Amazon GameLift Servers API, which is part of the AWS SDK. See [Amazon GameLift Servers SDKs for client services](https://docs.aws.amazon.com/gamelift/latest/developerguide/gamelift-supported.html#gamelift-supported-clients) to learn more about the AWS SDK and download the latest version. For API descriptions and functionality, see [Amazon GameLift Servers FlexMatch API reference (AWS SDK)](reference-awssdk-flex.md).
+ **Set up a matchmaking ticket system.** All matchmaking requests must have a unique ticket ID. Create a mechanism to generate unique ticket IDs and assign them to match requests. A ticket ID can use any string format, up to a maximum of 128 characters. 
+ **Collect information about your matchmaker.** Get the following information from your matchmaking configuration and rule set. 
  + Name of the matchmaking configuration resource.
  + The list of player attributes, which are defined in the rule set.
+ **Retrieve player data.** Set up a way to get relevant data for each player to include in your matchmaking requests. You need the player ID and player attribute values. If your rule set has latency rules or you want to use latency data when placing game sessions, collect latency data for each geographic location where the player is likely be slotted into a game. To obtain accurate latency measurements, use Amazon GameLift Servers's UDP ping beacons. These endpoints enable you to measure actual UDP network latency between player devices and each of the potential hosting locations, resulting in more accurate placement decisions than using ICMP pings. For more information on using UDP ping beacons to measure latency, refer to [UDP ping beacons](https://docs.aws.amazon.com/gameliftservers/latest/developerguide/reference-udp-ping-beacons.html).

# Request matchmaking for players


Add code to your game backend service to manage matchmaking requests to a FlexMatch matchmaker. The process of requesting FlexMatch matchmaking is identical for games that use FlexMatch with Amazon GameLift Servers hosting and for games that use FlexMatch as a standalone solution.

## To create a matchmaking request:


Call the Amazon GameLift Servers API [StartMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_StartMatchmaking.html). Each request must contain the following information.

**Matchmaker**  
The name of the matchmaking configuration to use for the request. FlexMatch places each request into the pool for the specified matchmaker, and the request is processed based on how the matchmaker is configured. This includes enforcing a time limit, whether to request player acceptance of matches, which queue to use when placing a resulting game session, etc. Learn more about matchmakers and rules sets in [Design a FlexMatch matchmaker](match-configuration.md). 

**Ticket ID**  
A unique ticket ID assigned to the request. Everything related to the request, including events and notifications, will reference the ticket ID. 

**Player data**  
List of players that you want to create a match for. If any of the players in the request do not meet match requirements, based on the match rules and latency minimums, the matchmaking request will never result in a successful match. You can include up to ten players in a match request. When there are multiple players in a request, FlexMatch tries to create a single match and assign all players to the same team (randomly selected). If a request contains too many players to fit in one of the match teams, the request will fail to be matched. For example, if you've set up your matchmaker to create 2v2 matches (two teams of two players), you cannot send a matchmaking request containing more than two players.  
A player (identified by their player ID) can only be included in one active matchmaking request at a time. When you create a new request for a player, any active matchmaking tickets with the same player ID are automatically canceled.
For each listed player, include the following data:  
+ *Player ID *– Each player must have a unique player ID, which you generate. See [Generate player IDs](https://docs.aws.amazon.com/gamelift/latest/developerguide/player-sessions-player-identifiers.html). 
**Important**  
When you create a new matchmaking request that contains a player ID that is already included in an existing active matchmaking request, the existing request is automatically cancelled. However, a `MatchmakingCancelled` event is not sent for the cancelled request. To monitor the status of existing matchmaking requests, use [DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html) to poll the request status at infrequent intervals (30-60 seconds). The cancelled request will show a status of `CANCELLED` with the reason `Cancelled due to duplicate player`.
+ *Player attributes* – If the matchmaker in use calls for player attributes, the request must provide those attributes for each player. The required player attributes are defined in the matchmaker's rule set, which also specifies the data type for the attribute. A player attribute is optional only when the rule set specifies a default value for the attribute. If the match request does not provide required player attributes for all players, the matchmaking request can never succeed. Learn more about matchmaker rule sets and player attributes in [Build a FlexMatch rule set](match-rulesets.md) and [FlexMatch rule set examples](match-examples.md).
+ *Player latencies* – If the matchmaker in use has a player latency rule, the request must report latency for each player. Player latency data is a list of one or more values per player. It represents the latency that the player experiences for regions in the matchmaker's queue. If no latency values for a player are included in the request, the player cannot be matched, and the request fails. To obtain accurate latency measurements, use Amazon GameLift Servers's UDP ping beacons. These endpoints enable you to measure actual UDP network latency between player devices and a potential hosting location, resulting in more accurate placement decisions than using ICMP pings. For more information on using UDP ping beacons to measure latency, refer to [UDP ping beacons](https://docs.aws.amazon.com/gameliftservers/latest/developerguide/reference-udp-ping-beacons.html).

## To retrieve match request details


After a match request is sent, you can view the request details by calling [DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html) with the request's ticket ID. This call returns the request information, including current status. Once a request has been successfully completed, the ticket also contains the information that a game client needs to connect to the match. 

## To cancel a match request


You can cancel a matchmaking request at any time by calling [StopMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_StopMatchmaking.html) with the request's ticket ID.

# Track matchmaking events


Set up notifications to track events that Amazon GameLift Servers emits for matchmaking processes. You can set up notifications either directly, by creating an SNS topic, or by using Amazon EventBridge. For more information on setting up notifications, see [Set up FlexMatch event notifications](match-notification.md). Once you've set up notifications, add a listener on your client service to detect the events and respond as needed. 

It's also a good idea to back up notifications by periodically polling for status updates when a significant period of time passes without notification. To minimize impact on matchmaking performance, be sure to poll only after waiting at least 30 seconds after the matchmaking ticket was submitted or after the last received notification.

Retrieve a matchmaking request ticket, including current status, by calling [DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html) with the request's ticket ID. We recommend polling no more than once every 10 seconds. This approach is for use during low-volume development scenarios only.

**Note**  
You should set up your game with event notifications before you have high-volume matchmaking usage, such as with pre-production load testing. All games in public release should use notifications regardless of volume. The continuous polling approach is only appropriate for games in development with low matchmaking usage.

# Request player acceptance


If you're using a matchmaker that has player acceptance turned on, add code to your client service to manage the player acceptance process. The process of managing player acceptances is identical for games that use FlexMatch with Amazon GameLift Servers-managed hosting and for games that use FlexMatch as a standalone solution.

**Request player acceptance for a proposed match:**

1. **Detect when a proposed match needs player acceptance.** Monitor the matchmaking ticket to detect when the status changes to `REQUIRES_ACCEPTANCE`. A change to this status triggers the FlexMatch event `MatchmakingRequiresAcceptance`.

1. **Get acceptances from all players.** Create a mechanism to present the proposed match details to every player in the matchmaking ticket. Players must be able to indicate that they either accept or reject the proposed match. You can retrieve match details by calling [DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html). Players have a limited time to respond before the matchmaker withdraws the proposed match and moves on.

1. **Report player responses to FlexMatch.** Report player responses by calling [AcceptMatch](https://docs.aws.amazon.com/gamelift/latest/apireference/API_AcceptMatch.html) with either accept or reject. All players in a matchmaking request must accept the match for it to go forward.

1. **Handle tickets with failed acceptances.** A request fails when any player in the proposed match either rejects the match or fails to respond by the acceptance time limit. Tickets for players who did accept the match are automatically returned to the ticket pool. Tickets for players who did not accept the match move to FAILURE status and are no longer processed. For tickets with multiple players, if any players in the ticket did not accept the match, the entire ticket fails.

# Connect to a match


Add code to your client service to handle a successfully formed match (status `COMPLETED` or event `MatchmakingSucceeded`). This includes notifying the match's players and handing off connection information to their game clients. 

For games that use Amazon GameLift Servers managed hosting, when a matchmaking request is successfully fulfilled, the game session connection information is added to the matchmaking ticket. Retrieve a completed matchmaking ticket by calling [DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html). Connection information includes the game session's IP address and port, as well as a player session ID for each player ID. Learn more in [GameSessionConnectionInfo](https://docs.aws.amazon.com/gamelift/latest/apireference/API_GameSessionConnectionInfo.html). Your game client can use this information to connect directly to the game session for the match. The connection request should include a player session ID and a player ID. This data associates the connected player to the game session's match data, which includes team assignments (see [GameSession](https://docs.aws.amazon.com/gamelift/latest/apireference/API_GameSession.html)). 

For games that use other hosting solutions, including Amazon GameLift Servers FleetIQ, you must build in a mechanism to enable match players to connect to the appropriate game session. 

# Sample matchmaking requests


The following code snippets build matchmaking requests for several different matchmakers. As described, a request must provide the player attributes that are required by the matchmaker in use, as defined in the matchmaker's rule set. The attribute provided must use the same data type, number (N) or string (S) that is defined in the rule set. 

```
# Uses matchmaker for two-team game mode based on player skill level
def start_matchmaking_for_cowboys_vs_aliens(config_name, ticket_id, player_id, skill, team):
    response = gamelift.start_matchmaking(
        ConfigurationName=config_name,
        Players=[{
            "PlayerAttributes": {
                "skill": {"N": skill}
            },
            "PlayerId": player_id,
            "Team": team
        }],
        TicketId=ticket_id)

# Uses matchmaker for monster hunter game mode based on player skill level
def start_matchmaking_for_players_vs_monster(config_name, ticket_id, player_id, skill, is_monster):
    response = gamelift.start_matchmaking(
        ConfigurationName=config_name,
        Players=[{
            "PlayerAttributes": {
                "skill": {"N": skill},
                "desiredSkillOfMonster": {"N": skill},
                "wantsToBeMonster": {"N": int(is_monster)}
            },
            "PlayerId": player_id
        }],
        TicketId=ticket_id)

# Uses matchmaker for brawler game mode with latency
def start_matchmaking_for_three_team_brawler(config_name, ticket_id, player_id, skill, role):
    response = gamelift.start_matchmaking(
        ConfigurationName=config_name,
        Players=[{
            "PlayerAttributes": {
                "skill": {"N": skill},
                "character": {"S": [role]},
            },
            "PlayerId": player_id,
            "LatencyInMs": { "us-west-2": 20}
        }],
        TicketId=ticket_id)

# Uses matchmaker for multiple game modes and maps based on player experience
def start_matchmaking_for_multi_map(config_name, ticket_id, player_id, skill, maps, modes):
    response = gamelift.start_matchmaking(
        ConfigurationName=config_name,
        Players=[{
            "PlayerAttributes": {
                "experience": {"N": skill},
                "gameMode": {"SL": modes},
                "mapPreference": {"SL": maps}
            },
            "PlayerId": player_id
        }],
        TicketId=ticket_id)
```