<!--
{
  "documentType" : "article",
  "framework" : "GameKit",
  "identifier" : "/documentation/GameKit/finding-multiple-players-for-a-game",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Finding multiple players for a game"
}
-->

# Finding multiple players for a game

Discover and invite other players to participate in a real-time game.

## Discussion

GameKit enables the user of your game, called the *local player*, to discover and connect with other players in real-time multiplayer games.

For design guidance, see [Human Interface Guidelines > Technologies > Game Center > Multiplayer](https://developer.apple.com/design/human-interface-guidelines/game-center#Multiplayer).

### Choose whether to use the Game Center interface

You can present a Game Center interface that allows the local player to invite nearby or recent players, friends, contacts, Game Center or Message groups, and anyone with a phone number or email address.

The default interface allows the player to use automatic matches to fill any empty slots. The local player can see the status of players accepting or declining their invitations, as they invite additional players or remove players. Once the number of players that you specify accept their invitations, the local player can start gameplay. Optionally, your game can continue processing responses to invitations, and GameKit can continue automatching to fill empty slots until the maximum number of players that you specify join the game.

![Screenshot of the matchmaker view controller showing the local player choosing other players and the Invite Friends and Start Game buttons they click to send invitations and begin gameplay.](images/com.apple.gamekit/media-3854543@2x.png)

Alternatively, you can present your own custom interface to invite players, invite specific players, or let Game Center automatch players without presenting an interface.

In your code, you create a match request and optionally present the matchmaker view controller. Then you implement methods to present the appropriate interface to all players during the process of receiving and accepting invitations.

### Create a match request

First, create a [`GKMatchRequest`](/documentation/GameKit/GKMatchRequest) object and set the parameters of the game. You can set the number of players, apply groups and attributes to filter the matches, specify the game mode, and set other criteria.

```swift
let request = GKMatchRequest()
request.minPlayers = 2
request.maxPlayers = 10
```

Use the [`maxPlayersAllowedForMatch(of:)`](/documentation/GameKit/GKMatchRequest/maxPlayersAllowedForMatch(of:)) method to get the maximum number of players for your match type ([`GKMatchType.peerToPeer`](/documentation/GameKit/GKMatchType/peerToPeer), [`GKMatchType.hosted`](/documentation/GameKit/GKMatchType/hosted), or [`GKMatchType.turnBased`](/documentation/GameKit/GKMatchType/turnBased)).

If you use game-specific matchmaking rules to find players, set the [`queueName`](/documentation/GameKit/GKMatchRequest/queueName) and optionally, the [`properties`](/documentation/GameKit/GKMatchRequest/properties) properties of the [`GKMatchRequest`](/documentation/GameKit/GKMatchRequest) object. Also, set the [`minPlayers`](/documentation/GameKit/GKMatchRequest/minPlayers) and [`maxPlayers`](/documentation/GameKit/GKMatchRequest/maxPlayers) properties within the bounds of the rule set’s `minPlayers` and `maxPlayers` fields. For more information, see [Finding players using matchmaking rules](doc://com.apple.documentation/documentation/GameKit/finding-players-using-matchmaking-rules).

### Enable the local player to choose other players

The local player can choose opponents from the Game Center interface when you present a [`GKMatchmakerViewController`](/documentation/GameKit/GKMatchmakerViewController) object and handle the resulting invitation events.

Pass the [`GKMatchRequest`](/documentation/GameKit/GKMatchRequest) object to the [`GKMatchmakerViewController`](/documentation/GameKit/GKMatchmakerViewController) initializer and set the view controller’s delegate to your game object before you present it. Use the <doc://com.apple.documentation/documentation/UIKit/UIViewController/present(_:animated:completion:)> or equivalent method to present the matchmaker view controller, in which the local player can choose players or automatch to fill empty slots.

```swift
// Present the interface where the player selects opponents and starts the game.
if let viewController = GKMatchmakerViewController(matchRequest: request) {
    viewController.matchmakerDelegate = self
    rootViewController?.present(viewController, animated: true) { }
}
```

Optionally, configure the view controller before you present it:

- To show only nearby players for games where players need to be in the same room, as in augmented reality (<doc://com.apple.documentation/documentation/ARKit>) games, set the [`matchmakingMode`](/documentation/GameKit/GKMatchmakerViewController/matchmakingMode) property to [`GKMatchmakingMode.nearbyOnly`](/documentation/GameKit/GKMatchmakingMode/nearbyOnly).
- To use automatch only to connect with other players, set the mode to [`GKMatchmakingMode.automatchOnly`](/documentation/GameKit/GKMatchmakingMode/automatchOnly), or to invite players without using automatch, set the mode to [`GKMatchmakingMode.inviteOnly`](/documentation/GameKit/GKMatchmakingMode/inviteOnly).
- To allow the local player to start gameplay with a minimum number of players, while Game Center continues to fill empty slots in the background, set the [`canStartWithMinimumPlayers`](/documentation/GameKit/GKMatchmakerViewController/canStartWithMinimumPlayers) property to <doc://com.apple.documentation/documentation/Swift/true>. Then design your game to progressively add players as they accept their invitations.

Players automatically have the ability to chat with other players using FaceTime. The view controller shows a SharePlay button, in addition to the Invite Players and Quick Match buttons. To implement a custom group activities experience, see [`startGroupActivity(playerHandler:)`](/documentation/GameKit/GKMatchmaker/startGroupActivity(playerHandler:)). For macOS apps, add the Group Activities capability to your Xcode project to show the SharePlay button.

![Screenshot of the matchmaker view controller showing the SharePlay, Invite Players, and Quick Match buttons that players click to start matching players.](images/com.apple.gamekit/media-4278455@2x.png)

Then adopt the [`GKLocalPlayerListener`](/documentation/GameKit/GKLocalPlayerListener) and [`GKMatchmakerViewControllerDelegate`](/documentation/GameKit/GKMatchmakerViewControllerDelegate) protocols to implement methods that keep track of the invitations GameKit sends and the invitations players accept. To receive the [`GKInviteEventListener`](/documentation/GameKit/GKInviteEventListener) callbacks that the `GKLocalPlayerListener` protocol includes, register your game object with the local player object:

```swift
GKLocalPlayer.local.register(self)
```

### Accept an invitation from another player

Game Center sends invitations to the players asynchronously. When a player accepts an invitation from another player, GameKit notifies Game Center and invokes the `GKInviteEventListener` [`player(_:didAccept:)`](/documentation/GameKit/GKInviteEventListener/player(_:didAccept:)) method.

![Diagram showing the Game Center sending invitations to Player B and Player C, then the delegate method sent to the listener object when Player B accepts the invitation.](images/com.apple.gamekit/media-3697898@2x.png)

Implement the [`player(_:didAccept:)`](/documentation/GameKit/GKInviteEventListener/player(_:didAccept:)) method to present the matchmaker view controller in the invitation state so the recipient of the invitation can see the progress as other players accept their invitations. Create the matchmaker view controller by passing the invite to the initializer, and then present it.

```swift
func player(_ player: GKPlayer, didAccept invite: GKInvite) {
    // Present the matchmaker view controller in the invitation state.
    if let viewController = GKMatchmakerViewController(invite: invite) {
        viewController.matchmakerDelegate = self
        rootViewController?.present(viewController, animated: true) { }
    }
}
```

### Start the game when players accept invitations

The matchmaker view controller shows the players who received or accepted invitations. When all the players accept their invitations, GameKit invokes the `GKMatchmakerViewControllerDelegate` [`matchmakerViewController(_:didFind:)`](/documentation/GameKit/GKMatchmakerViewControllerDelegate/matchmakerViewController(_:didFind:)) method in the app instances for all players in the game, including the player who sent the invitations.

![Diagram showing Player A inviting Player B and Player C, and then the matchmaker view controller delegate being notified when all the players accept their invitations.](images/com.apple.gamekit/media-3697899@2x.png)

Implement the [`matchmakerViewController(_:didFind:)`](/documentation/GameKit/GKMatchmakerViewControllerDelegate/matchmakerViewController(_:didFind:)) method to dismiss the view controller and start your game. If the player count is low or players accept invitations quickly, you can add a delay before you dismiss the view controller, so players see the outgoing invitations before you start the game.

```swift
func matchmakerViewController(_ viewController: GKMatchmakerViewController,
                                  didFind match: GKMatch) {
    // Dismiss the view controller.
    viewController.dismiss(animated: true, completion: nil)

    // Set the match delegate.
    match.delegate = myGame
          
    // Start the game with the players in the match.
}
```

Then use the [`GKMatch`](/documentation/GameKit/GKMatch) object that GameKit passes to this delegate method to get the player list and send data from one player to another during the game.

### Handle matchmaking cancellations and errors

When the local player closes the matchmaker interface without choosing players, or some other error occurs while choosing players, implement the [`matchmakerViewControllerWasCancelled(_:)`](/documentation/GameKit/GKMatchmakerViewControllerDelegate/matchmakerViewControllerWasCancelled(_:)) delegate method to dismiss the view controller.

```swift
func matchmakerViewControllerWasCancelled(_ viewController: GKMatchmakerViewController) 
{
    // Dismiss the view controller.
    viewController.dismiss(animated:true)
}
```

Also, implement the [`matchmakerViewController(_:didFailWithError:)`](/documentation/GameKit/GKMatchmakerViewControllerDelegate/matchmakerViewController(_:didFailWithError:)) method to handle any errors that might occur. For possible errors, see [`GKError`](/documentation/GameKit/GKError).

### Let Game Center match the player with others

GameKit can automatch the local player without presenting the Game Center matchmaking interface where players invite others. To start automatch, pass the match request to the shared [`GKMatchmaker`](/documentation/GameKit/GKMatchmaker) object using the [`findMatch(for:withCompletionHandler:)`](/documentation/GameKit/GKMatchmaker/findMatch(for:withCompletionHandler:)) method.

```swift
// Start automatch.
do {
    match = try await GKMatchmaker.shared().findMatch(for: request)
} catch {
    print("Error: \(error.localizedDescription).")
    return
}
```

If another game instance starts automatch at the same time, the [`findMatch(for:withCompletionHandler:)`](/documentation/GameKit/GKMatchmaker/findMatch(for:withCompletionHandler:)) method creates a match with that player and returns the corresponding [`GKMatch`](/documentation/GameKit/GKMatch) object. To receive a callback when players join the match, set the match’s delegate to an object that implements the [`match(_:player:didChange:)`](/documentation/GameKit/GKMatchDelegate/match(_:player:didChange:)-8ohgr) delegate method.

Implement the [`match(_:player:didChange:)`](/documentation/GameKit/GKMatchDelegate/match(_:player:didChange:)-8ohgr) method to check whether the `state` parameter is [`GKPlayerConnectionState.connected`](/documentation/GameKit/GKPlayerConnectionState/connected) before starting the game and accessing the player’s properties, such as the display name and avatar.

```swift
func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState) {
    switch state {
    case .connected:
        // Load the opponent's avatar.
        player.loadPhoto(for: GKPlayer.PhotoSize.small) { (image, error) in
            if let image {
                self.opponentAvatar = Image(uiImage: image)
            }
            else if let error {
                print("Error: \(error.localizedDescription).")
            }
        }
    case .disconnected:
        // Handle disconnected state.
    default:
        // Handle unknown state.
    }
}
```

After enough players join the match, or if the player cancels automatch, call the shared `GKMatchmaker` [`finishMatchmaking(for:)`](/documentation/GameKit/GKMatchmaker/finishMatchmaking(for:)) method to stop GameKit from looking for players.

Alternatively, to invite specific players without presenting an interface, set the match request’s [`recipients`](/documentation/GameKit/GKMatchRequest/recipients) property before invoking the [`findMatch(for:withCompletionHandler:)`](/documentation/GameKit/GKMatchmaker/findMatch(for:withCompletionHandler:)) method.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)