Leaderboards for VIVEPORT API

The VIVEPORT SDK supports persistent leaderboards with automatically ordered entries. These leaderboards can be used to display global and local rankings in your content.

How to use Leaderboards API

Note

Remember that you should call Top Level API - Api.Init() and Stats & Achievements API - UserStats.IsReady() to setup the SDK library and client runtime before you call UserStats APIs. And please remember to call Top Level API - Api.Shutdown() to teardown the library runtime after you finish using VIVEPORT SDK.

Download a Leaderboard

  1. Leaderboards for your content can be downloaded by calling DownloadLeaderboardScores().
  • If LeaderBoardRequestType is GlobalData or LocalData, RangeStart and RangeEnd are for rank start to rank end. And the number of RangeStart and RangeEnd are positive numbers.
  • If LeaderBoardRequestType is GlobalDataAroundUser or LocalDataAroundUser, RangeStart and RangeEnd are based on the user’s rank. And the rank range is before and after the user’s rank.
  • LeaderBoardTimeRange is for the data you get is for AllTime, Daily, Weekly, or Monthly.
  1. Then you can retrieve leaderboard scores by calling GetLeaderboardScore(), retrieve the leaderboard score count by calling GetLeaderboardScoreCount(). You can also get the leaderboard sort method by calling GetLeaderboardSortMethod() and display type by calling GetLeaderboardDisplayType().
  2. If LeaderBoardRequestType is GlobalData or LocalData, the rank data you retrieve from GetLeaderboardScore() starts from 0.

Upload a Score

You can use UploadLeaderboardScore() to upload score changes.

Important

Please see the Error Codes and Trouble Shooting pages to know what to do when you got problems using the VIVEPORT SDK.

Step by step: Leaderboards

First, you need to login to VIVEPORT.

  1. Before using developer console, you must install VIVEPORT, and login to your HTC Account.

    _images/ViveLogin.png
  2. Sign in to the developer console using your HTC Account and password.

    _images/DeveloperLogin.png
  3. On Developers console, on My Content -> Manage page, click Add new experience button to create an experiene to obtain VIVEPORT ID.

    _images/AddNewExperience.png
  4. After creating, you can get VIVEPORT ID from below screen:

    _images/AppID.png
  5. Then use Add leaderboard button to create a new leaderboard.

    _images/Add_Leaderboard.png
  6. Fill in all fields for the new leaderboard: ( please refer Glossary in detail )

    _images/Leaderboard.png

Detailed Example in Unity

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/* Language: C# */
using UnityEngine;
using System;
using Viveport;

public class ViveportDemo : MonoBehaviour
{
   private int nInitValue = 0, nResult = 0;
#if UNITY_ANDROID
   private int nWidth - 150, nHeight = 100;
#else
   private int nWidth = 110, nHeight = 40;
#endif
   private int nXStart = 10, nYStart = 35;
   private string stringToEdit = "Input Stats name";
   private string StatsCount = "Input max index";
   private string leaderboardToEdit = "ID_Leaderboard1";
   private string leaderboardUserName = "Karl";
   private string leaderboardScore = "1000";
   private static bool bInit = true, bIsReady = false;

   static string VIVEPORT_ID = "bd67b286-aafc-449d-8896-bb7e9b351876";

   // Use this for initialization
   void Start ()
   {
       Api.Init(InitStatusHandler, VIVEPORT_ID);
   }

   void OnGUI()
   {
       GUIStyle CustButton = new GUIStyle("button");
    #if UNITY_ANDROID
       CustButton.fontSize = 23;
    #endif
       if (bInit == false)
          GUI.contentColor = Color.white;
       else
          GUI.contentColor = Color.grey;

       // Init function
       if (GUI.Button(new Rect(nXStart, nYStart, nWidth, nHeight), "Init", CustButton))
       {
          if (bInit == false)
             Api.Init(InitStatusHandler, VIVEPORT_ID);
       }

       if (bInit == true)
          GUI.contentColor = Color.white;
       else
          GUI.contentColor = Color.grey;

       // Shutdown function
       if (GUI.Button(new Rect((nXStart + 1 * (nWidth + 10)), nYStart, nWidth, nHeight), "Shutdown"
                                , CustButton))
       {
          if (bInit == true)
             Api.Shutdown(ShutdownHandler);
       }

       // IsReady function
       if (GUI.Button(new Rect((nXStart + 2 * (nWidth + 10)), nYStart, nWidth, nHeight), "IsReady"
                                , CustButton))
       {
          if (bInit == true)
             UserStats.IsReady(IsReadyHandler);
       }


       /***************************************************************************/
       /*                          Leaderboard sample code                        */
       /***************************************************************************/

       if (bInit == true && bIsReady == true)
          GUI.contentColor = Color.white;
       else
          GUI.contentColor = Color.grey;

       leaderboardToEdit = GUI.TextField(new Rect(10, 3 * nWidth + 20, 160, 20), leaderboardToEdit
                                                  , 150);

       // DownloadLeaderboardScores function for global around user data.
       if (GUI.Button(new Rect(nXStart, nYStart + 3 * nWidth + 20, nWidth, nHeight), "DL Around"
                      , CustButton))
       {
          if (bInit == true && bIsReady == true)
          {
             UserStats.DownloadLeaderboardScores(DownloadLeaderboardHandler, leaderboardToEdit,
                                                 UserStats.LeaderBoardRequestType.GlobalDataAroundUser,
                                                 UserStats.LeaderBoardTimeRange.AllTime, -5, 5);
             Viveport.Core.Logger.Log("DownloadLeaderboardScores");
          }
          else
             Viveport.Core.Logger.Log("Make sure init is successful.");
       }

       // DownloadLeaderboardScores for global data function.
       if (GUI.Button(new Rect(nXStart + 1 * (nWidth + 10), nYStart + 3 * nWidth + 20, nWidth,
                      nHeight), "DL not Around", CustButton))
       {
          if (bInit == true && bIsReady == true)
          {
             UserStats.DownloadLeaderboardScores(DownloadLeaderboardHandler, leaderboardToEdit,
                                                 UserStats.LeaderBoardRequestType.GlobalData,
                                                 UserStats.LeaderBoardTimeRange.AllTime, 0, 10);
             Viveport.Core.Logger.Log("DownloadLeaderboardScores");
          }
          else
             Viveport.Core.Logger.Log("Make sure init is successful.");
       }

       leaderboardScore = GUI.TextField(new Rect(10 + 160, 3 * nWidth + 20, 160, 20),
                                        leaderboardScore, 50);

       // UploadLeaderboardScore function.
       if (GUI.Button(new Rect(nXStart + 2 * (nWidth + 10), nYStart + 3 * nWidth + 20, nWidth,
                      nHeight), "Upload LB", CustButton))
       {
          if (bInit == true && bIsReady == true)
          {
             UserStats.UploadLeaderboardScore(UploadLeaderboardScoreHandler, leaderboardToEdit,
                                              int.Parse(leaderboardScore));
             Viveport.Core.Logger.Log("UploadLeaderboardScore");
          }
          else
             Viveport.Core.Logger.Log("Make sure init is successful.");
       }

       // GetLeaderboardScoreCount function.
       if (GUI.Button(new Rect(nXStart + 3 * (nWidth + 10), nYStart + 3 * nWidth + 20, nWidth,
                      nHeight), "Get LB count", CustButton))
       {
          if (bInit == true && bIsReady == true)
          {
             nResult = UserStats.GetLeaderboardScoreCount();
             Viveport.Core.Logger.Log("GetLeaderboardScoreCount=> " + nResult);
          }
          else
             Viveport.Core.Logger.Log("Make sure init is successful.");
       }

       // GetLeaderboardScore function.
       if (GUI.Button(new Rect(nXStart + 4 * (nWidth + 10), nYStart + 3 * nWidth + 20, nWidth,
                      nHeight), "Get DL data", CustButton))
       {
          if (bInit == true && bIsReady == true)
          {
             int nResult = (int)UserStats.GetLeaderboardScoreCount();

             Viveport.Core.Logger.Log("GetLeaderboardScoreCount => " + nResult);

             for (int i = 0; i < nResult; i++)
             {
                 Viveport.Leaderboard lbdata;
                 lbdata = UserStats.GetLeaderboardScore(i);
                 Viveport.Core.Logger.Log("UserName = " + lbdata.UserName + ", Score = " +
                                          lbdata.Score + ", Rank = " + lbdata.Rank);
             }
          }
          else
             Viveport.Core.Logger.Log("Make sure init is successful.");
       }

       // GetLeaderboardSortMethod function.
       if (GUI.Button(new Rect(nXStart + 5 * (nWidth + 10), nYStart + 3 * nWidth + 20, nWidth,
                      nHeight), "Get Sort Method", CustButton))
       {
          if (bInit == true && bIsReady == true)
          {
             int nResult = (int)UserStats.GetLeaderboardSortMethod();
             Viveport.Core.Logger.Log("GetLeaderboardSortMethod=> " + nResult);
          }
          else
             Viveport.Core.Logger.Log("Make sure init is successful.");
       }

       // GetLeaderboardDisplayType function.
       if (GUI.Button(new Rect(nXStart + 6 * (nWidth + 10), nYStart + 3 * nWidth + 20, nWidth,
                      nHeight), "Get Disp Type", CustButton))
       {
          if (bInit == true && bIsReady == true)
          {
             int nResult = (int)UserStats.GetLeaderboardDisplayType();
             Viveport.Core.Logger.Log("GetLeaderboardDisplayType=> " + nResult);
          }
          else
             Viveport.Core.Logger.Log("Make sure init is successful.");
       }

   }

   private static void InitStatusHandler(int nResult)
   {
      if (nResult == 0)
      {
         bInit = true;
         bIsReady = false;
         Viveport.Core.Logger.Log("InitStatusHandler is successful");
      }
      else
      {
         bInit = false;
         Viveport.Core.Logger.Log("IsReadyHandler error : " + nResult);
      }
   }

   private static void IsReadyHandler(int nResult)
   {
      if (nResult == 0)
      {
         bIsReady = true;
         Viveport.Core.Logger.Log("IsReadyHandler is successful");
      }
      else
      {
         bIsReady = false;
         Viveport.Core.Logger.Log("IsReadyHandler error: " + nResult);
      }
   }

   private static void ShutdownHandler(int nResult)
   {
      if (nResult == 0)
      {
         bInit = false;
         bIsReady = false;
         Viveport.Core.Logger.Log("ShutdownHandler is successful");
      }
      else
         Viveport.Core.Logger.Log("ShutdownHandler error: " + nResult);
   }

   private static void DownloadLeaderboardHandler(int nResult)
   {
      if (nResult == 0)
         Viveport.Core.Logger.Log("DownloadLeaderboardHandler is successful");
      else
         Viveport.Core.Logger.Log("DownloadLeaderboardHandler error: " + nResult);
   }

   private static void UploadLeaderboardScoreHandler(int nResult)
   {
      if (nResult == 0)
         Viveport.Core.Logger.Log("UploadLeaderboardScoreHandler is successful.");
      else
         Viveport.Core.Logger.Log("UploadLeaderboardScoreHandler error : " + nResult);
   }
}

Detailed Example in Unreal

ViveportUserStatsDemo.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "Components/ActorComponent.h"
#include "ViveportApi.h"
#include "ViveportUserStats.h"
#include "ViveportType.h"

#include "ViveportUserStatsDemo.generated.h"

UCLASS(ClassGroup = (Viveport), meta = (BlueprintSpawnableComponent))
class VIVEPORTSDK_API UViveportUserStatsDemo : public UActorComponent
{
    GENERATED_BODY()

public:
    // Sets default values for this component's properties
    UViveportUserStatsDemo();

    // Called when the game starts
    void BeginPlay() override;

    void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

    // Called every frame
    void TickComponent(float DeltaTime,
                       LevelTick TickType,
                       FActorComponentTickFunction* ThisTickFunction
                      ) override;

    /** The APP ID for auth verify */
    FString VIVEPORT_ID = "bd67b286-aafc-449d-8896-bb7e9b351876";

public:

    class MyInitCallback : public ViveportApiStatus
    {
    public:
        void OnSuccess(
            ) override;
        void OnFailure(int errorCode
            ) override;
    };

    class MyIsReadyStatus : public ViveportApiStatus
    {
    public:
        void OnSuccess(
            ) override;
        void OnFailure(int errorCode
            ) override;
    };

    class MyDownloadLeaderboardScoreStatus : public ViveportApiStatus
    {
    public:
        void OnSuccess(
            ) override;
        void OnFailure(int errorCode
            ) override;
    };

    class MyUploadLeaderboardScoreStatus : public ViveportApiStatus
    {
    public:
        void OnSuccess(
            ) override;
        void OnFailure(int errorCode
            ) override;
    };

    class MyShutdownCallback : public ViveportApiStatus
    {
    public:
        void OnSuccess(
            ) override;
        void OnFailure(int error_code
            ) override;
    };
};

ViveportUserStatsDemo.cpp

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "ViveportSDKPrivatePCH.h"
#include "ViveportUserStatsDemo.h"

UViveportUserStatsDemo::MyInitCallback myInitCallback;
UViveportUserStatsDemo::MyShutdownCallback myShutdownCallback;
UViveportUserStatsDemo::MyIsReadyStatus myIsReadyStatus;
UViveportUserStatsDemo::MyDownloadLeaderboardScoreStatus myDownloadLeaderboardScoreStatus;
UViveportUserStatsDemo::MyUploadLeaderboardScoreStatus myUploadLeaderboardScoreStatus;

//Leaderboard information
FString fLeaderBoardName = "ID_Leaderboard1";
int upload_score = 10;
//Download Leaderboard conditions
UELeaderboardDataDownload leaderboard_scope = u_ELeaderboardDataDownloadLocal;
UELeaderboardDataTimeRange leaderboard_time_range = u_ELeaderboardDataScropeAllTime;
int range_start = 0;
int range_end = 10;

// Sets default values for this component's properties
UViveportUserStatsDemo::UViveportUserStatsDemo()
{
    // Set this component to be initialized when the game starts, and to be ticked every
    // frame.  You can turn these featuresoff to improve performance if you don't need them.
    bWantsBeginPlay = true;
    PrimaryComponentTick.bCanEverTick = true;
}

// Called when the game starts
void UViveportUserStatsDemo::BeginPlay()
{
    Super::BeginPlay();
    UViveportApi::Init(&myInitCallback, VIVEPORT_ID);
}

void UViveportUserStatsDemo::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
    Super::EndPlay(EndPlayReason);
    UViveportApi::Shutdown(&myShutdownCallback);
}

// Called every frame
void UViveportUserStatsDemo::TickComponent(float DeltaTime,
                                           ELevelTick TickType,
                                           FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}

void UViveportUserStatsDemo::MyInitCallback::OnSuccess()
{
    FString fstring("Init success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
    UViveportUserStats::IsReady(&myIsReadyStatus);
}

void UViveportUserStatsDemo::MyInitCallback::OnFailure(int error)
{
    FString fstring("Init failure. error code=" + error);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportUserStatsDemo::MyIsReadyStatus::OnSuccess()
{
    FString fstring("IsReady success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
    UViveportUserStats::UploadLeaderboardScore(&myUploadLeaderboardScoreStatus,
                                               fLeaderBoardName,
                                               upload_score);
}

void UViveportUserStatsDemo::MyIsReadyStatus::OnFailure(int error)
{
    const FString fstring = FString::Printf(TEXT("IsReady failure. error=%d"), error);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportUserStatsDemo::MyDownloadLeaderboardScoreStatus::OnSuccess()
{
    FString fstring("DownloadLeaderboardScore success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    fstring = FString::Printf(TEXT("GetLeaderboardSortMethod=%d\nGetLeaderboardDisplayType=%d"),
                                (int) UViveportUserStats::GetLeaderboardSortMethod(),
                                (int) UViveportUserStats::GetLeaderboardDisplayType()
                             );
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    int size = UViveportUserStats::GetLeaderboardScoreCount();
    for (int i = 0; i < size; i++)
    {
        ULeaderboardScore leaderboardScore = UViveportUserStats::GetLeaderboardScore(i);
        fstring = FString::Printf(TEXT("rank=%d, name=%s, score=%d"),
                                        leaderboardScore.Rank,
                                        *leaderboardScore.UserName,
                                        leaderboardScore.Score);
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
    }

}

void UViveportUserStatsDemo::MyDownloadLeaderboardScoreStatus::OnFailure(int error)
{
    const FString fstring = FString::Printf(TEXT("DownloadLeaderboardScore failure. error=%d"),
                                            error);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportUserStatsDemo::MyUploadLeaderboardScoreStatus::OnSuccess()
{
    FString fstring("UploadLeaderboardScore success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    UViveportUserStats::DownloadLeaderboardScores(&myDownloadLeaderboardScoreStatus,
                                                    fLeaderBoardName,
                                                    leaderboard_scope,
                                                    leaderboard_time_range,
                                                    range_start,
                                                    range_end
                                                );
}

void UViveportUserStatsDemo::MyUploadLeaderboardScoreStatus::OnFailure(int error)
{
    const FString fstring = FString::Printf(TEXT("UploadLeaderboardScore failure. error=%d"),
                                            error);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportUserStatsDemo::MyShutdownCallback::OnSuccess()
{
    FString fstring("Shutdown success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportUserStatsDemo::MyShutdownCallback::OnFailure(int error_code)
{
    FString fstring = FString::Printf(TEXT("Shutdown failure. error=%d"), error_code);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}