Skip to main content
Version: v3

Achievements Guide

This page shows you how to integrate the Achievements service into your game. The Achievements service is based on TDS Authentication (TDSUser). You can read more about this in TDS Authentication > Guide.

Install the SDK

Please make sure that you have already created the game, configured the project, and initialized the project according to the TapSDK Quickstart. Once you have completed these steps, you can proceed to add the TapAchievement module from the TapSDK downloaded from the Downloads page:

"dependencies":{
...
// Achievements service
"com.taptap.tds.achievement": "https://github.com/TapTap/TapAchievement-Unity.git#3.28.2",
}

Register Callbacks

The Achievements SDK has several callbacks that are triggered when the data is initialized, when the data cannot be initialized, and when there is a progress update. The data initialization callback is particularly important as it is required for the SDK to work properly. If the data cannot be initialized, please either prompt the user or try to initialize the data again at another time.

Prerequisite

TapTap.Achievement depends on the TapTap.Bootstrap library.

Namespace

using TapTap.Achievement;

To register callbacks:

TapAchievement.RegisterCallback(IAchievementCallback callback);

private class AchievementCallback:IAchievementCallback
{
public void OnAchievementSDKInitSuccess()
{
// The Achievement SDK is initialized
}

public void OnAchievementSDKInitFail(TapError errorCode)
{
if (errorCode != null)
{
// Failed to initialize the SDK
}
}

public void OnAchievementStatusUpdate(TapAchievementBean bean, TapError errorCode)
{
if (errorCode != null)
{
// Failed to update achievements
return;
}

if (bean != null)
{
// Achievements updated
}
}
}

Initialize the Data

Since the Achievements service keeps track of the user’s achievement data locally, please make sure to initialize the data when the user is logged in. If the user switches to a different account, be sure to call the interface for initializing the data again. Failure to do so may result in the achievement data for different accounts being mixed up.

This step is asynchronous, which means that you should not proceed until you have received a successful callback.

TapAchievement.InitData();

Get All Achievements

You can get all achievements from either the local cache or the server. The local cache is refreshed when you successfully invoke the data initialization interface. It is also refreshed when you proactively invoke the data fetching interface.

If you need to fetch the latest data from the server while the player is playing, you can use the data fetching interface. Most of the time you just need to load the data from the local cache.

// Get local data
TapAchievement.GetLocalAllAchievementList((list, code) =>
{
if (code != null)
{
// Failed to get all achievements
}
else
{
// Got all achievements successfully
});
}
// Fetch data from the server
TapAchievement.FetchAllAchievementList((list, code) =>
{
if (code != null)
{
// Failed to fetch all achievements
}
else
{
// Fetched all achievements successfully
});
}

Get Current User’s Achievements

You can get the current user’s achievements from either the local cache or the server. The local cache is merged with the server data when you successfully invoke the data initialization interface (if different steps are tracked for the same achievement in the server and the local cache, the larger one is kept). They are also merged when you proactively invoke the data fetching interface.

The local data is often more accurate than the server data because the server data may be out of date due to previous synchronization failures.

// Get local data
TapAchievement.GetLocalUserAchievementList((list, code) =>
{
if (code != null)
{
// Failed to get user’s achievements
}
else
{
// Got user’s achievements successfully
});
}
// Fetch data from the server
TapAchievement.FetchUserAchievementList((list, code) =>
{
if (code != null)
{
// Failed to fetch user’s achievements
}
else
{
// Fetched user’s achievements successfully
});
}

Get an Achievement (Directly)

// displayID is the Achievement ID you configured on the Developer Center
TapAchievement.Reach("displayID");

Add Steps to an Accumulation Achievement

There are two ways to add steps to an accumulation achievement. The first is to call growSteps with the number of steps to add (for example, enter 5 to add 5 steps). The second is to use makeSteps with the total number of steps (for example, enter 100 to set the total number of steps to 100). Internally, the SDK would calculate the total number of steps when you call growSteps.

// displayID is the Achievement ID you configured on the Developer Center
TapAchievement.GrowSteps("displayID", step);
TapAchievement.MakeSteps("displayID", step);

Set Toasts

By default, the SDK automatically displays a toast when the player gets an achievement. You can turn off toasts using the following interface:

TapAchievement.SetShowToast(bool isShow);

Show Achievements

The SDK comes with a page that shows all the achievements the player has gotten:

TapAchievement.ShowAchievementPage();

Interpreting Achievement Data

public string displayId;              // Achievement ID
public int visible = VisibleFalse; // Whether the achievement is hidden
public string title; // Name
public string subTitle; // Description
public string achieveIcon; // Icon
public int step; // Total steps
public bool fullReached; // Whether the player has gotten the achievement
public int reachedStep; // Current steps
public long reachedTime; // When the player has gotten the achievement
public AchievementStats stats; // Rarity

Internationalization

The Achievements service supports multiple languages:

tip

When the data is initialized, only the achievement data for the current language is synchronized from the server. To switch to another language after initialization, call fetchAllAchievementList and fetchUserAchievementList.

TapCommon.SetLanguage(TapLanguage.AUTO);

The following languages are supported:

namespace TapTap.Common
{
public enum TapLanguage
{
AUTO = 0, // Auto
ZH_HANS = 1, // Simplified Chinese
EN = 2, // English
ZH_HANT = 3, // Traditional Chinese
JA = 4, // Japanese
KO = 5, // Korean
TH = 6, // Thai
ID = 7, // Indonesian
}
}

When Auto is selected, the SDK will set the language based on the system language. If the system language is not among the supported languages listed above, the SDK will set the language according to the region configured when the SDK is initialized. If the region is China mainland, the language will be Simplified Chinese. Otherwise, the language will be English.

REST API

Now let’s look at the REST API provided by the Achievements service. You can write your own programs or scripts to invoke these interfaces to perform server-side administrative operations.

Request Format

The body of any request sent to the REST API must be a JSON object. The Content-Type in the HTTP header should be application/json.

Requests sent to the server are authenticated using the key-value pairs in the HTTP Header:

KeyValueDescription
X-TDS-Id{{clientId}}The game’s Client Id, which can be found on the Developer Center.
X-TDS-Server-Secret{{serverSecret}}The game’s Server Secret, which can be found on the Developer Center.

Find out more about application credentials here.

In addition to providing the Client Id through the X-TDS-Id HTTP Header, you must also provide the same Client Id in the URL.

When obtaining achievements, you must specify the language in the URL. See Language Codes for more information.

If there is an error, the HTTP status code 500 will be returned, like:

{
"code": "500",
"msg": "成就服务忙,稍后请求",
}

Get All Achievements

Below is the interface for retrieving all the game’s achievements. Make sure you include the language in the URL.

curl -X GET \
-H "X-TDS-Id: {{clientId}}" \
-H "X-TDS-Server-Secret: {{serverSecret}}" \
https://tds-tapsdk.cn.tapapis.com/achievement/open/v1/clients/{{clientId}}/achievements/languages/<lang>

The response body looks like this:

{
"success": true,
"data": {
"list": [
{
"achievement_id": "Achievement ID",
"client_id": "Client ID",
"achievement_open_id": "Achievement open ID (a custom achievement ID specified by the developer when creating the achievement; this is the unique identifier used when submitting achievement data with the SDK)",
"achievement_type": "Achievement type; 1 means basic achievement; 99 means Platinum Achievement",
"is_hide": "Whether the achievement is hidden; 0 means not hidden; 1 means hidden",
"count_step": "Total steps; if the achievement is not an accumulation achievement, this will be 1",
"show_order": "The order of the achievement; if the achievement is a Platinum Achievement, this will be 0",
"achievement_config_out_dto": {
"achievement_config_id": "The achievement’s configuration ID",
"achievement_id": "Achievement ID",
"language_id": "Language ID",
"achievement_icon": "Link to the achievement’s icon",
"achievement_title": "Achievement name",
"achievement_sub_title": "Achievement description"
},
"achievement_rarity": {
"rarity": "Rarity rate",
"level": "Rarity; 1 means Common; 2 means Uncommon; 3 means Rare; 4 means Ultra Rare"
}
}
]
}
}

Get a User’s Achievements

Below is the interface for retrieving a user’s achievements. Make sure you include the player’s account objectId and language code in the URL.

curl -X GET \
-H "X-TDS-Id: {{clientId}}" \
-H "X-TDS-Server-Secret: {{serverSecret}}" \
https://tds-tapsdk.cn.tapapis.com/achievement/open/v1/clients/{{clientId}}/users/<objectId>/achievements/languages/<lang>

The response body looks like this:

{
"success": true,
"data": {
"list": [
{
"achievement_id": "Achievement ID",
"client_id": "Client ID",
"achievement_open_id": "Achievement open ID (an ID assigned to the achievement when it is added on the Developer Center)",
"achievement_type": "Achievement type; 1 means basic achievement; 99 means Platinum Achievement",
"is_hide": "Whether the achievement is hidden; 0 means not hidden; 1 means hidden",
"count_step": "Total steps; if the achievement is not an accumulation achievement, this will be 1",
"show_order": "The order of the achievement; if the achievement is a Platinum Achievement, this will be 0",
"achievement_config_out_dto": {
"achievement_config_id": "The achievement’s configuration ID",
"achievement_id": "Achievement ID",
"language_id": "Language ID",
"achievement_icon": "Link to the achievement’s icon",
"achievement_title": "Achievement name",
"achievement_sub_title": "Achievement description"
},
"achievement_rarity": {
"rarity": "Rarity rate",
"level": "Rarity; 1 means Common; 2 means Uncommon; 3 means Rare; 4 means Ultra Rare"
},
"user_achievement_id": "User achievement ID",
"complete_time": "Time of completion (in miliseconds)",
"completed_step": "Steps completed",
"full_completed": "Whether completed; true means yes; false means no"
}
]
}
}

Submit Achievements

Below is the interface for submitting one or more achievements that a player has earned. The achievements submitted will be added to the list of achievements the player has already earned.

curl -X POST \
-H "X-TDS-Id: {{clientId}}" \
-H "X-TDS-Server-Secret: {{serverSecret}}" \
-H "Content-Type: application/json" \
-d '{"data": [{"user_id": <objectId>, "list":
[{
"achievement_id": "Achievement ID",
"achievement_open_id": "Achievement open ID (a custom achievement ID specified by the developer when creating the achievement; this is the unique identifier used when submitting achievement data with the SDK)",
"complete_time": "Time of completion (in miliseconds)",
"completed_step": "Steps completed"
}]
}]
}' \
https://tds-tapsdk.cn.tapapis.com/achievement/open/v1/clients/{{clientId}}/achievements

The response body looks like this:

{
"success": true,
"data": {
"list": [
{
"user_id": "ObjectId",
"result_list": [
{
"result": "Whether this data has been successfully submitted; true means yes; false means no"
"code": "Is 0 if succeeded and the error code if not"
"msg": "Is not included if succeeded and the error message if not"
}
]
}
]
}
}

Language Codes

The REST API accepts language codes defined by ISO 639-1. For example, en means English and jp means Japanese. There are a couple of exceptions:

  1. For languages not included in ISO 639-1, the language codes defined in ISO 632-2 are used. For example, fil means Filipino.
  2. When a language cannot be represented by a language code, the location code defined in ISO 3166-1 will be attached. For example, zh_CN means Simplified Chinese.

The following language codes are supported by the REST API:

CodeLanguage
zh_CNSimplified Chinese
zh_TWTraditional Chinese
en_USEnglish (US)
ja_JPJapanese
ko_KRKorean
pt_PTPortuguese
vi_VNVietnamese
hi_INHindi
id_IDIndonesian
ms_MYMalay
th_THThai
es_ESSpanish
afAfrikaans
amAmharic
bgBulgarian
caCatalan
hrCroatian
csCzech
daDanish
nlDutch
etEstonian
filFilipino
fiFinnish
frFrench
deGerman
elGreek
heHebrew
huHungarian
isIcelandic
itItalian
lvLatvian
ltLithuanian
noNorwegian
plPolish
roRomanian
ruRussian
srSerbian
skSlovak
slSlovenian
swSwahili
svSwedish
trTurkish
ukUkrainian
zuZulu

Keep in mind that some of the languages listed above are only supported by the REST API but not the client SDK.

Video Tutorials

You can refer to the video tutorial:How to Integrate Achievements in Games to learn how to access achievements in Untiy projects.

For more video tutorials, see Developer Academy. As the SDK features are constantly being improved, there may be inconsistencies between the video tutorials and the new SDK features, so the current documentation should prevail.