Achievements

Achievements are a great way to track what a player has done in your game and to give the player more incentive to keep playing your game. An achievement represents a quantitative goal that the player can accomplish in your game. As the local player plays your game, they make progress towards completing the achievement. When the player meets or exceeds the goal, the achievement is considered earned, and the player is rewarded. Your game defines the goal and the game mechanics that describe how a player earns the achievement. In practice, Game Center does not need to know anything about your game design; it only knows what progress the player has made towards an achievement.

In Game Center, an achievement earns a player achievement points. When you define an achievement, you decide how many points it is worth. A player can see the total number of points that can potentially be earned in your game as well as how many points he or she has currently earned. The Game Center app allows players to compare their achievements with those of friends; this comparison screen includes the total points earned.

When you add an achievement to your game, you configure how the achievement is granted and how it is described to the player. You also design the game mechanics that allow the player to make progress towards completing the achievement.

Checklist for Supporting Achievements

To add achievements to your game, you need to take the following steps:

  1. Before you add achievements, add code to authenticate the local player.
  2. Design your game’s achievements. See Designing an Achievement.
  3. Go to iTunes Connect and configure the achievements for your game. You provide all of the data needed to display achievements to the player. See Configuring Achievements in iTunes Connect.
  4. Add code to report the local player’s progress to Game Center. By storing the progress on Game Center, you also make the player’s progress visible in the Game Center app. See Reporting Achievement Progress to Game Center.
  5. Add code to load the local player’s previous progress on achievements from Game Center. The local player’s progress should be loaded shortly after the player is successfully authenticated. See Loading Achievement Progress.

Reporting Achievement Progress to Game Center

Your game should report progress to Game Center whenever the player makes progress towards completing an achievement. By storing progress information in Game Center, you gain a few benefits:

  • The Game Center app can display the player’s progress towards the achievement.

  • If a player has multiple devices, your game on another device can retrieve the player’s progress towards achievements.

You store the a user’s progress towards an achievement using the PercentComplete property of ISN_GKAchievement object. When you report progress to Game Center, two things happen:

  • If the achievement was previously hidden, it is revealed to the player. The achievement is revealed even if your player has made no actual progress on the achievement (a percentage of 0.0).

  • If the reported value is higher than the previous value reported for the achievement, the value on Game Center is updated to the new value. Players never lose progress on achievements.

When the progress reaches 100 percent, the achievement is marked as completed, and both the image and completed description appear when the player views the achievements screen.

Whether reporting progress on a single achievement or on multiple achievements at once, your game rarely needs to do anything specific when an error occurs. If an error occurs, such as when a network is not available, Game Kit automatically resends the data at an appropriate time.

Best Practices for Reporting Achievement Progress

When designing a game that uses Game Center achievements, you need to balance the need to be responsive to the player against your goal to use as few device resources as possible. With those two concepts in mind, consider the following practices:

  • Report progress on an achievement as soon as the player makes progress. Don’t delay reporting until a later time; if a player earns an achievement, the banner should be displayed immediately.

  • Report progress only when the player has actually made further progress. Do not report changes to Game Center if the player has not made progress, because it consumes network resources without actually changing the state of the data on Game Center.

  • If your game displays a custom banner or indicator when a player earns an achievement, set the ShowsCompletionBanner property to NO before reporting the achievement to Game Center.

See the example how to report a single achievement progress in a code snippet below:

using SA.iOS.GameKit;
...
ISN_GKAchievement achievement = new ISN_GKAchievement("itunes.achievement.id");
achievement.PercentComplete = 50.0f;
achievement.Report((result) => {
	if(result.IsSucceeded) {
		Debug.Log("Achievement reported");
	} else {
		Debug.Log("Achievement report failed! Code: " + result.Error.Code + " Message: " + result.Error.Message);
	}
});

Whenever you need to submit more achievement updates at the same time, you may use the ReportAchievements method. Calling this method reports each of the achievements in the array Processing multiple achievements at once allows the entire operation to be processed more efficiently.

See the example below:

using SA.iOS.GameKit;
...
ISN_GKAchievement achievement1 = new ISN_GKAchievement("itunes.achievement.id.1");
achievement.PercentComplete = 50.0f;

ISN_GKAchievement achievement2 = new ISN_GKAchievement("itunes.achievement.id.2");
achievement.PercentComplete = 70.0f;

var achievements = new List<ISN_GKAchievement>() { achievement1, achievement2 };

ISN_GKAchievement.ReportAchievements(achievements, (result) => {
    if (result.IsSucceeded) {
        Debug.Log("Achievements reported");
    } else {
        Debug.Log("Achievements report failed! Code: " + result.Error.Code + " Message: " + result.Error.Message);
    }
});

Loading Achievement Progress

You load the local player’s current progress information from Game Center by calling the LoadAchievements method. If the operation completes successfully, it returns an array of ISN_GKAchievement objects, one object for each achievement your game previously reported progress for.

using SA.iOS.GameKit;
...
ISN_GKAchievement.LoadAchievements((result) => {
	if(result.IsSucceeded) {
		foreach(ISN_GKAchievement achievement in result.Achievements) {
			Debug.Log(achievement.Identifier);
			Debug.Log(achievement.PercentComplete);
			Debug.Log(achievement.LastReportedDate);
			Debug.Log(achievement.Completed);
		}
	} else {
		Debug.Log("LoadAchievements failed! Code: " + result.Error.Code + " Message: " + result.Error.Message);
	}
});

Resetting Achievement Progress

You may want to allow the player to reset their progress on achievements in your game. See ResetAchievements for information on how to reset the player’s progress.

When your game resets a player’s progress on achievements, all progress information is lost. Hidden achievements, if previously shown, are hidden again until your game reports progress on them. For example, if the only reason those achievements were originally hidden was that they were associated with an In-App Purchase, then you would reveal those achievements again.

using SA.iOS.GameKit;
...
ISN_GKAchievement.ResetAchievements((result) => {
     if (result.IsSucceeded) {
        Debug.Log("Reset Achievements Success");
     } else {
        Debug.Log("Reset Achievements failed! Code: " + result.Error.Code + " Message: " + result.Error.Message);
     }
});