How to Create a Level System#

This guide will show you how to create a linear skill tree whereby a set of skills directly follow from one to the next in a set. To illustrate this we will create a simple leveling system with ten levels. The levels are defined as skill definitions and then a single archetype serves as a single classification for the entire level system.

Pre-requisites#

This guide assumes you have read and understand the following documents:

Events#

In order to make a proper leveling system we will need to track two types of telemetry events: GainXP and SkillUnlocked. The GainXP is a custom event type we will use to track the amount of experience a given persona has earned over time. The SkillUnlocked event type is used to chain a set of levels together so that level 10 follows 9 which follows level 8 and so on.

Whenever a persona has earned experience an event will be sent to the telemetry_services system with the type GainXP and the value property set to the amount of experience actually earned.

This can be implemented as a server side feature (recommended) or by the client directly.

Sending events from a service#

1const data: any = {
2    type: "GainXP",
3    userId: user.uid,
4    personaUid: user.personas[0].uid,
5    value: 100,
6};
7
8EventUtils.record(new Event(config, user.uid, data));

Sending events from the SDK#

 1Event eventObj = new Event
 2{
 3    Type = "GainXP",
 4    UserId = ClientSDK.LoggedInUser.uid,
 5    PersonaUid = ClientSDK.LoggedInUser.personas[0].uid,
 6
 7     Value = 100
 8};
 9
10EventService eventService = ServiceFactory.GetService<EventService>();
11await eventService.Create(eventObj);
1std::shared_ptr<models::Event> eventObj(new models::Event);
2eventObj->SetType("GainXP");
3eventObj->SetUserUid(ClientSDK.LoggedInUser.uid);
4eventObj->SetPersonaUid(ClientSDK.LoggedInUser.personas[0].uid);
5eventObj->Set("value", 100);
6
7auto eventService = ServiceFactory::GetInstance()->GetService<services::EventService>();
8eventService->Create(eventObj).Wait();

Defining Levels as Skills#

Now that we have a mechanism to track experience we can define our levels. Each level has have an associated skill definition where the requirements include the amount of relative experience that must be reached (from the prior level) as well as the previous level that must be required.

The first level in our system is very simple as it has no requirements. All players must start at level 1. Thus the skill definition looks as follows:

1{
2   "uid": "13105623-a639-46ac-a3e9-9efffcd3133b",
3   "name": "level_1",
4   "title": "Level 1",
5   "description": "You are level 1.",
6   "icon": "level1.png",
7   "requirements": []
8}

In order to create this definition with the service we send a POST request to the /skills endpoint containing the above as the payload:

 1 POST /skills HTTP/1.1
 2 Authorization: jwt <admin_token>
 3 Content-Type: application/json
 4
 5{
 6    "uid": "13105623-a639-46ac-a3e9-9efffcd3133b",
 7    "name": "level_1",
 8    "title": "Level 1",
 9    "description": "You are level 1.",
10    "icon": "level1.png",
11    "requirements": []
12}

For level two we will add some experience as the sole requirement. We will choose a value of 1000 which means that at ten of the aforementioned events would need to be created in order to unlock the level:

 1{
 2    "uid": "82ab33b5-b470-4c51-9e15-5e60945410ae",
 3    "name": "level_2",
 4    "title": "Level 2",
 5    "description": "You are level 2.",
 6    "icon": "level2.png",
 7    "requirements": [
 8        {
 9            "type": "GainXP",
10            "title": "Earn experience",
11            "description": "Requires 1,000 experience.",
12            "icon": "xp.png",
13            "value": 1000
14        }
15    ]
16}

Just like the level 1 we create this definition by POSTing to the /skills endpoint:

POST /skills HTTP/1.1
Authorization: jwt <admin_token>
Content-Type: application/json

{
   "uid": "82ab33b5-b470-4c51-9e15-5e60945410ae",
   "name": "level_2",
   "title": "Level 2",
   "description": "You are level 2.",
   "icon": "level2.png",
   "requirements": [
      {
         "type": "GainXP",
         "title": "Earn experience",
         "description": "Requires 1,000 experience.",
         "icon": "xp.png",
         "value": 1000
      }
   ]
}

For level 3 we will set an experience requirement as well as a SkillUnlocked requirement chaining it to level 2. Note that the value of the requirement will be the uid of the level two skill definition which in the above example is 1ea968f3-ca97-4d8c-8c9d-63d183942be0. This level will require 5000 experience points to achieve:

 1{
 2   "uid": "0e9c15d2-a3a6-4042-9801-cd493faf6c8b",
 3   "name": "level_3",
 4   "title": "Level 3",
 5   "description": "You are level 3.",
 6   "icon": "level3.png",
 7   "requirements": [
 8      {
 9         "type": "GainXP",
10         "title": "Earn experience",
11         "description": "Requires 7,000 experience.",
12         "icon": "xp.png",
13         "value": 8000
14      },
15      {
16         "type": "SkillUnlocked",
17         "title": "Level 2",
18         "description": "Requires level 2.",
19         "icon": "level2.png",
20         "value": "82ab33b5-b470-4c51-9e15-5e60945410ae"
21      }
22   ]
23}

We can now create the remaining levels the same way as level 3, where the SkillUnlocked requirement references the level before it. Our final level, level 10 will thus look like the following:

 1{
 2    "uid": "e6f09514-bc8d-4f5c-9726-22fad002804a",
 3    "name": "level_10",
 4    "title": "Level 10",
 5    "description": "You are level 10.",
 6    "icon": "level10.png",
 7    "requirements": [
 8       {
 9          "type": "GainXP",
10          "title": "Earn experience",
11          "description": "Requires 729,000 experience.",
12          "icon": "xp.png",
13          "value": 729000
14       },
15       {
16          "type": "SkillUnlocked",
17          "title": "Level 9",
18          "description": "Requires level 9.",
19          "icon": "level9.png",
20          "value": "73bc15d8-1c15-40c3-aebc-bcac584c505b"
21       }
22    ]
23}

Below is the complete list of levels from 1 to 10 from our example:

  1[
  2    {
  3        "uid": "13105623-a639-46ac-a3e9-9efffcd3133b",
  4        "name": "level_1",
  5        "title": "Level 1",
  6        "description": "You are level 1.",
  7        "icon": "level1.png",
  8        "requirements": []
  9    },
 10    {
 11        "uid": "82ab33b5-b470-4c51-9e15-5e60945410ae",
 12        "name": "level_2",
 13        "title": "Level 2",
 14        "description": "You are level 2.",
 15        "icon": "level2.png",
 16        "requirements": [
 17            {
 18                "type": "GainXP",
 19                "title": "Earn experience",
 20                "description": "Requires 1,000 experience.",
 21                "icon": "xp.png",
 22                "value": 1000
 23            }
 24        ]
 25    },
 26    {
 27        "uid": "0e9c15d2-a3a6-4042-9801-cd493faf6c8b",
 28        "name": "level_3",
 29        "title": "Level 3",
 30        "description": "You are level 3.",
 31        "icon": "level3.png",
 32        "requirements": [
 33            {
 34                "type": "GainXP",
 35                "title": "Earn experience",
 36                "description": "Requires 7,000 experience.",
 37                "icon": "xp.png",
 38                "value": 8000
 39            },
 40            {
 41                "type": "SkillUnlocked",
 42                "title": "Level 2",
 43                "description": "Requires level 2.",
 44                "icon": "level2.png",
 45                "value": "82ab33b5-b470-4c51-9e15-5e60945410ae"
 46            }
 47        ]
 48    },
 49    {
 50        "uid": "a985e26f-5393-45bb-a91d-2abd7206dc01",
 51        "name": "level_4",
 52        "title": "Level 4",
 53        "description": "You are level 4.",
 54        "icon": "level4.png",
 55        "requirements": [
 56            {
 57                "type": "GainXP",
 58                "title": "Earn experience",
 59                "description": "Requires 27,000 experience.",
 60                "icon": "xp.png",
 61                "value": 27000
 62            },
 63            {
 64                "type": "SkillUnlocked",
 65                "title": "Level 3",
 66                "description": "Requires level 3.",
 67                "icon": "level3.png",
 68                "value": "0e9c15d2-a3a6-4042-9801-cd493faf6c8b"
 69            }
 70        ]
 71    },
 72    {
 73        "uid": "f03fbab4-092e-44b9-ac29-9c81a3a8a1b5",
 74        "name": "level_5",
 75        "title": "Level 5",
 76        "description": "You are level 5.",
 77        "icon": "level5.png",
 78        "requirements": [
 79            {
 80                "type": "GainXP",
 81                "title": "Earn experience",
 82                "description": "Requires 64,000 experience.",
 83                "icon": "xp.png",
 84                "value": 64000
 85            },
 86            {
 87                "type": "SkillUnlocked",
 88                "title": "Level 4",
 89                "description": "Requires level 4.",
 90                "icon": "level4.png",
 91                "value": "a985e26f-5393-45bb-a91d-2abd7206dc01"
 92            }
 93        ]
 94    },
 95    {
 96        "uid": "3a69bb8c-1d51-4815-b3ea-2d4a61b00e19",
 97        "name": "level_6",
 98        "title": "Level 6",
 99        "description": "You are level 6.",
100        "icon": "level6.png",
101        "requirements": [
102            {
103                "type": "GainXP",
104                "title": "Earn experience",
105                "description": "Requires 125,000 experience.",
106                "icon": "xp.png",
107                "value": 125000
108            },
109            {
110                "type": "SkillUnlocked",
111                "title": "Level 5",
112                "description": "Requires level 5.",
113                "icon": "level5.png",
114                "value": "f03fbab4-092e-44b9-ac29-9c81a3a8a1b5"
115            }
116        ]
117    },
118    {
119        "uid": "d9b4af8e-1e60-4e3f-8676-9396aca589b2",
120        "name": "level_7",
121        "title": "Level 7",
122        "description": "You are level 7.",
123        "icon": "level7.png",
124        "requirements": [
125            {
126                "type": "GainXP",
127                "title": "Earn experience",
128                "description": "Requires 216,000 experience.",
129                "icon": "xp.png",
130                "value": 216000
131            },
132            {
133                "type": "SkillUnlocked",
134                "title": "Level 6",
135                "description": "Requires level 6.",
136                "icon": "level6.png",
137                "value": "3a69bb8c-1d51-4815-b3ea-2d4a61b00e19"
138            }
139        ]
140    },
141    {
142        "uid": "b56f9ecb-3e45-4764-aa45-5a08878ae35e",
143        "name": "level_8",
144        "title": "Level 8",
145        "description": "You are level 8.",
146        "icon": "level8.png",
147        "requirements": [
148            {
149                "type": "GainXP",
150                "title": "Earn experience",
151                "description": "Requires 343,000 experience.",
152                "icon": "xp.png",
153                "value": 343000
154            },
155            {
156                "type": "SkillUnlocked",
157                "title": "Level 7",
158                "description": "Requires level 7.",
159                "icon": "level7.png",
160                "value": "d9b4af8e-1e60-4e3f-8676-9396aca589b2"
161            }
162        ]
163    },
164    {
165        "uid": "73bc15d8-1c15-40c3-aebc-bcac584c505b",
166        "name": "level_9",
167        "title": "Level 9",
168        "description": "You are level 9.",
169        "icon": "level9.png",
170        "requirements": [
171            {
172                "type": "GainXP",
173                "title": "Earn experience",
174                "description": "Requires 512,000 experience.",
175                "icon": "xp.png",
176                "value": 512000
177            },
178            {
179                "type": "SkillUnlocked",
180                "title": "Level 8",
181                "description": "Requires level 8.",
182                "icon": "level8.png",
183                "value": "b56f9ecb-3e45-4764-aa45-5a08878ae35e"
184            }
185        ]
186    },
187    {
188        "uid": "e6f09514-bc8d-4f5c-9726-22fad002804a",
189        "name": "level_10",
190        "title": "Level 10",
191        "description": "You are level 10.",
192        "icon": "level10.png",
193        "requirements": [
194            {
195                "type": "GainXP",
196                "title": "Earn experience",
197                "description": "Requires 729,000 experience.",
198                "icon": "xp.png",
199                "value": 729000
200            },
201            {
202                "type": "SkillUnlocked",
203                "title": "Level 9",
204                "description": "Requires level 9.",
205                "icon": "level9.png",
206                "value": "73bc15d8-1c15-40c3-aebc-bcac584c505b"
207            }
208        ]
209    }
210]

Creating the Archetype Definition#

It is necessary to create an archetype for our set of levels. The archetype contains descriptive information about it as well as a list of the root skills in the tree. In this case, our root skills are level 1 and level 2. The system automatically traverses these root skills for children referenced as requirements to build the large tree(s):

 1 {
 2     "name": "levels",
 3     "title": "Levels",
 4     "description": "All levels that persona can achieve.",
 5     "icon": "levels.png",
 6     "skills": [
 7         "13105623-a639-46ac-a3e9-9efffcd3133b",
 8         "82ab33b5-b470-4c51-9e15-5e60945410ae"
 9     ]
10 }

Note that if level 2 is modified to incldue level 1 as a requirement then list of skills for the archetype can be reduced to only level 1.

The archetype is then created by sending a POST request to the /archetypes endpoint:

 1POST /archetypes HTTP/1.1
 2Authorization: jwt <admin_token>
 3Content-Type: application/json
 4
 5{
 6    "name": "levels",
 7    "title": "Levels",
 8    "description": "All levels that persona can achieve.",
 9    "icon": "levels.png",
10    "skills": [
11        "13105623-a639-46ac-a3e9-9efffcd3133b",
12        "82ab33b5-b470-4c51-9e15-5e60945410ae"
13    ]
14}

Enabling an archetype for a given persona#

Now that our levels system has been created we can now enable it for personas so that they start tracking progress.

To enable an archetype for a given persona a PUT request is sent to the PUT /personas/{personaUid}/archetypes/{archetypeUid} endpoint. The request requires a payload containing the enabled state to set.

As an example imagine we have a persona with uid 4d1710e8-912e-4671-94d2-eaf51c301dcf. The request to enable the levels archetype would thus be:

1PUT /personas/4d1710e8-912e-4671-94d2-eaf51c301dcf/archetypes/019c6c67-983a-42de-8754-16b671b04ab1 HTTP/1.1
2Authorization: jwt <user_token>
3Content-Type: application/json
4
5{
6    "enabled": true
7}

Retrieving Enabled Archetypes#

Once an archetype has been enabled for a given persona it is possible to retrieve the complete definition of the archetype including the entire tree of skills associated with it by performing a GET request to the GET /personas/{personaUid}/archetypes/{archetypeUid} endpoint.

For our above example this request would look like:

1 GET /personas/4d1710e8-912e-4671-94d2-eaf51c301dcf/archetypes/019c6c67-983a-42de-8754-16b671b04ab1 HTTP/1.1
2 Authorization: jwt <user_token>

The response of the above request will look like the following:

  1{
  2     "uid": "019c6c67-983a-42de-8754-16b671b04ab1",
  3     "dateCreated": "2024-07-16T16:55:38.041Z",
  4     "dateModified": "2024-07-16T16:55:38.041Z",
  5     "version": 0,
  6     "name": "levels",
  7     "title": "Levels",
  8     "description": "All levels that persona can achieve.",
  9     "icon": "levels.png",
 10     "productUid": null,
 11     "skills": [
 12         {
 13             "uid": "13105623-a639-46ac-a3e9-9efffcd3133b",
 14             "dateCreated": "2024-07-16T16:38:57.680Z",
 15             "dateModified": "2024-07-16T16:38:57.680Z",
 16             "version": 0,
 17             "name": "level_1",
 18             "title": "Level 1",
 19             "description": "You are level 1.",
 20             "icon": "level1.png",
 21             "productUid": null,
 22             "requirements": [],
 23             "data": null,
 24             "_id": "6696a221487df228f9156a2a"
 25         },
 26         {
 27             "uid": "82ab33b5-b470-4c51-9e15-5e60945410ae",
 28             "dateCreated": "2024-07-16T16:38:57.815Z",
 29             "dateModified": "2024-07-16T16:38:57.815Z",
 30             "version": 0,
 31             "name": "level_2",
 32             "title": "Level 2",
 33             "description": "You are level 2.",
 34             "icon": "level2.png",
 35             "productUid": null,
 36             "requirements": [
 37                 {
 38                     "type": "GainXP",
 39                     "title": "Earn experience",
 40                     "description": "Requires 1,000 experience.",
 41                     "icon": "xp.png",
 42                     "value": 1000
 43                 }
 44             ],
 45             "data": null,
 46             "_id": "6696a221487df228f9156a2b"
 47         },
 48         {
 49             "uid": "0e9c15d2-a3a6-4042-9801-cd493faf6c8b",
 50             "dateCreated": "2024-07-16T16:38:57.917Z",
 51             "dateModified": "2024-07-16T16:38:57.917Z",
 52             "version": 0,
 53             "name": "level_3",
 54             "title": "Level 3",
 55             "description": "You are level 3.",
 56             "icon": "level3.png",
 57             "productUid": null,
 58             "requirements": [
 59                 {
 60                     "type": "GainXP",
 61                     "title": "Earn experience",
 62                     "description": "Requires 7,000 experience.",
 63                     "icon": "xp.png",
 64                     "value": 8000
 65                 },
 66                 {
 67                     "type": "SkillUnlocked",
 68                     "title": "Level 2",
 69                     "description": "Requires level 2.",
 70                     "icon": "level2.png",
 71                     "value": "82ab33b5-b470-4c51-9e15-5e60945410ae"
 72                 }
 73             ],
 74             "data": null,
 75             "_id": "6696a221487df228f9156a2c"
 76         },
 77         {
 78             "uid": "a985e26f-5393-45bb-a91d-2abd7206dc01",
 79             "dateCreated": "2024-07-16T16:38:58.029Z",
 80             "dateModified": "2024-07-16T16:38:58.029Z",
 81             "version": 0,
 82             "name": "level_4",
 83             "title": "Level 4",
 84             "description": "You are level 4.",
 85             "icon": "level4.png",
 86             "productUid": null,
 87             "requirements": [
 88                 {
 89                     "type": "GainXP",
 90                     "title": "Earn experience",
 91                     "description": "Requires 27,000 experience.",
 92                     "icon": "xp.png",
 93                     "value": 27000
 94                 },
 95                 {
 96                     "type": "SkillUnlocked",
 97                     "title": "Level 3",
 98                     "description": "Requires level 3.",
 99                     "icon": "level3.png",
100                     "value": "0e9c15d2-a3a6-4042-9801-cd493faf6c8b"
101                 }
102             ],
103             "data": null,
104             "_id": "6696a222487df228f9156a2d"
105         },
106         {
107             "uid": "f03fbab4-092e-44b9-ac29-9c81a3a8a1b5",
108             "dateCreated": "2024-07-16T16:38:58.094Z",
109             "dateModified": "2024-07-16T16:38:58.094Z",
110             "version": 0,
111             "name": "level_5",
112             "title": "Level 5",
113             "description": "You are level 5.",
114             "icon": "level5.png",
115             "productUid": null,
116             "requirements": [
117                 {
118                     "type": "GainXP",
119                     "title": "Earn experience",
120                     "description": "Requires 64,000 experience.",
121                     "icon": "xp.png",
122                     "value": 64000
123                 },
124                 {
125                     "type": "SkillUnlocked",
126                     "title": "Level 4",
127                     "description": "Requires level 4.",
128                     "icon": "level4.png",
129                     "value": "a985e26f-5393-45bb-a91d-2abd7206dc01"
130                 }
131             ],
132             "data": null,
133             "_id": "6696a222487df228f9156a2e"
134         },
135         {
136             "uid": "3a69bb8c-1d51-4815-b3ea-2d4a61b00e19",
137             "dateCreated": "2024-07-16T16:38:58.198Z",
138             "dateModified": "2024-07-16T16:38:58.198Z",
139             "version": 0,
140             "name": "level_6",
141             "title": "Level 6",
142             "description": "You are level 6.",
143             "icon": "level6.png",
144             "productUid": null,
145             "requirements": [
146                 {
147                     "type": "GainXP",
148                     "title": "Earn experience",
149                     "description": "Requires 125,000 experience.",
150                     "icon": "xp.png",
151                     "value": 125000
152                 },
153                 {
154                     "type": "SkillUnlocked",
155                     "title": "Level 5",
156                     "description": "Requires level 5.",
157                     "icon": "level5.png",
158                     "value": "f03fbab4-092e-44b9-ac29-9c81a3a8a1b5"
159                 }
160             ],
161             "data": null,
162             "_id": "6696a222487df228f9156a2f"
163         },
164         {
165             "uid": "d9b4af8e-1e60-4e3f-8676-9396aca589b2",
166             "dateCreated": "2024-07-16T16:38:58.354Z",
167             "dateModified": "2024-07-16T16:38:58.354Z",
168             "version": 0,
169             "name": "level_7",
170             "title": "Level 7",
171             "description": "You are level 7.",
172             "icon": "level7.png",
173             "productUid": null,
174             "requirements": [
175                 {
176                     "type": "GainXP",
177                     "title": "Earn experience",
178                     "description": "Requires 216,000 experience.",
179                     "icon": "xp.png",
180                     "value": 216000
181                 },
182                 {
183                     "type": "SkillUnlocked",
184                     "title": "Level 6",
185                     "description": "Requires level 6.",
186                     "icon": "level6.png",
187                     "value": "3a69bb8c-1d51-4815-b3ea-2d4a61b00e19"
188                 }
189             ],
190             "data": null,
191             "_id": "6696a222487df228f9156a30"
192         },
193         {
194             "uid": "b56f9ecb-3e45-4764-aa45-5a08878ae35e",
195             "dateCreated": "2024-07-16T16:38:58.424Z",
196             "dateModified": "2024-07-16T16:38:58.424Z",
197             "version": 0,
198             "name": "level_8",
199             "title": "Level 8",
200             "description": "You are level 8.",
201             "icon": "level8.png",
202             "productUid": null,
203             "requirements": [
204                 {
205                     "type": "GainXP",
206                     "title": "Earn experience",
207                     "description": "Requires 343,000 experience.",
208                     "icon": "xp.png",
209                     "value": 343000
210                 },
211                 {
212                     "type": "SkillUnlocked",
213                     "title": "Level 7",
214                     "description": "Requires level 7.",
215                     "icon": "level7.png",
216                     "value": "d9b4af8e-1e60-4e3f-8676-9396aca589b2"
217                 }
218             ],
219             "data": null,
220             "_id": "6696a222487df228f9156a31"
221         },
222         {
223             "uid": "73bc15d8-1c15-40c3-aebc-bcac584c505b",
224             "dateCreated": "2024-07-16T16:38:58.547Z",
225             "dateModified": "2024-07-16T16:38:58.547Z",
226             "version": 0,
227             "name": "level_9",
228             "title": "Level 9",
229             "description": "You are level 9.",
230             "icon": "level9.png",
231             "productUid": null,
232             "requirements": [
233                 {
234                     "type": "GainXP",
235                     "title": "Earn experience",
236                     "description": "Requires 512,000 experience.",
237                     "icon": "xp.png",
238                     "value": 512000
239                 },
240                 {
241                     "type": "SkillUnlocked",
242                     "title": "Level 8",
243                     "description": "Requires level 8.",
244                     "icon": "level8.png",
245                     "value": "b56f9ecb-3e45-4764-aa45-5a08878ae35e"
246                 }
247             ],
248             "data": null,
249             "_id": "6696a222487df228f9156a32"
250         },
251         {
252             "uid": "e6f09514-bc8d-4f5c-9726-22fad002804a",
253             "dateCreated": "2024-07-16T16:38:58.601Z",
254             "dateModified": "2024-07-16T16:38:58.601Z",
255             "version": 0,
256             "name": "level_10",
257             "title": "Level 10",
258             "description": "You are level 10.",
259             "icon": "level10.png",
260             "productUid": null,
261             "requirements": [
262                 {
263                     "type": "GainXP",
264                     "title": "Earn experience",
265                     "description": "Requires 729,000 experience.",
266                     "icon": "xp.png",
267                     "value": 729000
268                 },
269                 {
270                     "type": "SkillUnlocked",
271                     "title": "Level 9",
272                     "description": "Requires level 9.",
273                     "icon": "level9.png",
274                     "value": "73bc15d8-1c15-40c3-aebc-bcac584c505b"
275                 }
276             ],
277             "data": null,
278             "_id": "6696a222487df228f9156a33"
279         }
280     ],
281     "data": null
282}

Retrieving Skill Progress#

The current progress of a persona for a given archetype can be retrieved using the /personas/{personaUid}/archetypes/{archetypeUid}/skills endpoint:

GET /personas/4d1710e8-912e-4671-94d2-eaf51c301dcf/archetypes/a3708071-cd11-498c-a886-29e089d859c0/skills HTTP/1.1
Authorization: jwt <user_token>