Game Center for iOS: Building a Turn-Based Game

In this tutorial, you’ll learn about authentication with Game Center and how its turn-based mechanics work. In the end, you’ll have the foundations of how to integrate a multiplayer game with GameCenter. By Ryan Ackermann.

4.5 (11) · 1 Review

Download materials
Save for later
Share

In September 2010, Apple released the GameKit framework, which allows developers to create social multiplayer games without needing to develop a back end. Since its initial release, Apple has added turn-based gaming, player photos, friend suggestions, achievement points and challenges. Although Apple has since scaled back Game Center and its integration with iOS, many games still use some of its features.

In this tutorial, you’ll add a turn-based multiplayer system to an existing game. You’ll learn about authentication with Game Center and how its turn-based mechanics work. In the end, you’ll have the foundations of how to integrate a multiplayer game with Game Center.

The game used in this tutorial is a Nine Men’s Morris clone named Nine Knights. Nine Men’s Morris is a simple strategy game dating back to the Roman Empire. There are three phases of the game: placing, moving and flying. The average length of a game is 5-30 minutes depending on the players’ skills.

Getting Started

Start by downloading the starter project using the Download Materials link at the top or bottom of this tutorial. After unzipping the downloaded materials, open Nine Knights.xcodeproj.

The sample project is a complete local multiplayer game. Build and run to see the menu scene. It contains a single play button.

A menu scene with a single play button

The main sections of the game that you’ll be working with are Models/GameModel.swift and the scenes in the Scenes group. The game model represents the game’s state and determines the gameplay logic, such as move validation. The menu scene takes care of presenting the game scene for now. Finally, the game scene is where all of the player facing gameplay happens.

Connecting To Game Center

Playing against yourself is fun, but it’s time to get connected with other people. Before you can use Game Center, you have to configure some things in the project and App Store Connect.

To get started, open the project file in Xcode. With the Nine Knights target selected, choose a unique bundle identifier under the Identity group.

editing the bundle identifier

Next, select the Capabilities tab. You’ll need to turn on the Game Center switch and the Push Notifications switch.

Enabling Game Center and push notifications via the capabilities tab

Enabling the Game Center capability is obvious, but you enable the Push Notifications capability so that the game can receive notifications when it’s the player’s turn. Believe it or not, that’s all of the configuration you must do in the project.

Next, head over to appstoreconnect.apple.com. After logging in, select My Apps and create a new app by selecting the plus button in the top left. Fill out the information in the form. Make sure to select iOS as the platform, and choose the Bundle ID that you configured in Xcode.

Note: If you don’t see the Bundle ID you registered using Xcode, you can create one manually in the developer portal.

Creating a new app in appstoreconnect.

After App Store Connect creates the app, select it. Then, navigate to the Features tab and select Game Center.

Select the plus button next to the Leaderboard section title to create a new leaderboard.

Note: This step may seem odd since this tutorial doesn’t cover leaderboards with Game Center. However, without this step, Game Center won’t recognize the game when attempting to authenticate.The game is not recognized by Game Center.

Select the Single Leaderboard option and fill out the next form however you want. Since this is a hack to get Game Center working correctly, the information used to fill out the leaderboard isn’t important. Make sure to add a language as well so App Store Connect can create the leaderboard.

Creating a leaderboard.

Once that’s done, select the save button, and you should now have a leaderboard configured with the app. Game Center authentication is now ready for you to use!

Authenticating with Game Center

Now that you have an app configured for Game Center, it’s time to use it. For Nine Knights, it makes the most sense to authenticate to Game Center right away. In some games, it might be more appropriate to wait to authenticate until the player indicates a desire to play online.

You’ll use a helper class to consolidate the logic for Game Center. That’s where you’ll add the logic to authenticate.

To get started, open Helpers/GameCenterHelper.swift and add the following properties below the CompletionBlock declaration:

// 1
static let helper = GameCenterHelper()

// 2
var viewController: UIViewController?

Here’s how it works:

  1. You use a singleton to easily provide access to the Game Center logic from anywhere in the app.
  2. You use this view controller when you present the Game Center authentication view controller.

You want to attempt Game Center authentication when you first create this helper class. Add the following override to accomplish this:

override init() {
  super.init()
  
  GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in
    if GKLocalPlayer.local.isAuthenticated {
      print("Authenticated to Game Center!")
    } else if let vc = gcAuthVC {
      self.viewController?.present(vc, animated: true)
    }
    else {
      print("Error authentication to GameCenter: " +
        "\(error?.localizedDescription ?? "none")")
    }
  }
}

If this API is confusing to you, don’t worry. It’s not normal to kick off important logic like authenticating as a result of setting a variable. Even though this may seem strange, it’s reasonably simple to use.

You can determine if the user successfully authenticates in your completion block by evaluating GKLocalPlayer.local.isAuthenticated. If the user needs to sign in to Game Center, iOS passes a view controller in the completion block for you to present. Finally, if anything goes wrong, you can handle the error that is also returned.

To see this in action, add the following to the bottom of viewDidLoad() in ViewControllers/GameViewController.swift:

GameCenterHelper.helper.viewController = self

Build and run to see this in action.

The Sign In view for Game Center.

After logging in using your Apple ID, you’ll see the familiar success banner along with a message in the console.

Successfully signed into Game Center

Authenticating to Game Center is straightforward. It primarily consists of setting the authenticateHandler variable and Game Center takes care of most of the logic for you.

Telling the App About Authentication

Right now, Game Center knows if the player is logged in or not, but the rest of the app does not. You’ll use NotificationCenter to alert other parts of the app when the player authenticates.

To accomplish this, add the following to the bottom of GameCenterHelper.swift:

extension Notification.Name {
  static let presentGame = Notification.Name(rawValue: "presentGame")
  static let authenticationChanged = Notification.Name(rawValue: "authenticationChanged")
}

This helper uses a few notifications, and here’s what they’ll do:

  1. presentGame notifies the menu scene to present an online game.
  2. authenticationChanged notifies the app of any authentication state changes.

To use the authentication notification, add the following to the top of the authenticateHandler block:

NotificationCenter.default
  .post(name: .authenticationChanged, object: GKLocalPlayer.local.isAuthenticated)

To use this notification, open Scenes/MenuScene.swift and add the following below the declaration of the localButton:

private var onlineButton: ButtonNode!

Additionally, setup the onlineButton at the end of the setUpScene(in:) method:

onlineButton = ButtonNode("Online Game", size: buttonSize) {
  print("Pressed the online button.")
}
onlineButton.isEnabled = false
runningYOffset -= sceneMargin + buttonSize.height
onlineButton.position = CGPoint(x: sceneMargin, y: runningYOffset)
addChild(onlineButton)

This button node’s configuration is similar to the local button, but it’s initially disabled until the player is authenticated.

Build and run.

The Game’s menu with a disabled Online Game button.

To update this button’s state when then player authenticates to Game Center, you’ll need to listen for the notification that the helper class fires.

To do so, add the following to the bottom of the MenuSceneclass:

// MARK: - Notifications

@objc private func authenticationChanged(_ notification: Notification) {
  onlineButton.isEnabled = notification.object as? Bool ?? false
}

Then, add the observer in didMove(to:):

NotificationCenter.default.addObserver(
  self,
  selector: #selector(authenticationChanged(_:)),
  name: .authenticationChanged,
  object: nil
)

Build and run.

The Online Game button becomes enabled when you sign into Game Center.

Great, now the online button shows the correct state.

There’s an issue with the button if you leave the menu scene. Starting a local game and then returning to the menu causes the button to become disabled again.

To fix this, open GameCenterHelper.swift and add the following computed property near the top of GameCenterHelper:

static var isAuthenticated: Bool {
  return GKLocalPlayer.local.isAuthenticated
}

Now, back in MenuScene.swift and, at the end of setUpScene(in:), instead of initially disabling the online button, check the current state like so:

onlineButton.isEnabled = GameCenterHelper.isAuthenticated