Profiles

Note

Stability: 3 - Stable

Overview

The Hydra Profile service powers a majority of the other services and features you will use when integrating Hydra into your game. Most times, a Profile is considered the user’s game account, usually associated with the platform that they are playing your game on (iOS, Android, etc). A Profile is used to store player stats and lifetime aggregates.

The data is schemaless, which means that you don’t need to specify ahead of time what keys exist on each Profile. All you need to do is identify what key-value pairs you want, and this will automatically be created and stored in the Profile.

Here is what a simple Profile would look like for a shooting game. This Profile contains this player’s account id, username, and various stats:

{
   "id":"51151a2d44d9054184000000",
   "created_at":"2013-02-08 15:30:53",
   "data":{
      "stats":{
         "reloads":15,
         "times_played":6,
         "times_hit":5,
         "shots_fired":122,
         "orbs_destroyed":4
      }
   },
   "account_id":"509be0ca30e6d844e5000039",
   "updated_at":"2013-02-08 15:30:53"
}

Profile creation actually happens automatically whenever your users trigger an event that results in a post to Hydra. As the developer, you can determine when a user first makes a request to Hydra (upon game loading, when their first match is complete, etc). Updating profiles will use the same profile calls that you would use on profile creation.

Account ID

You’ll notice in the above example that there is an account_id field. This value is set automatically upon the creation of a profile. It is a unique identifier that associates this profile with the user’s account.

Profile Keys / Stats

{
    "data":{
       "stats":{
          "reloads":15,
          "times_played":6,
          "times_hit":5,
          "shots_fired":122,
          "orbs_destroyed":4
       }
    }
}

Your profiles are used to store per-game data/stats for your players. You can name your keys whatever you want. The values, however, must be a string, number, boolean or array. You should aim to have brief, yet descriptive key names. Longer key names will cause a Profile to be larger, which could lead to longer request times when interacting with our services.

Stats for the profile can either be incremented, decremented or set. You’ll want to be careful to minimize the number of API calls that your game makes by defining key parts in your game where a profile needs to be updated (such as at the end of a game session). You’ll want to store your data in local variables during gameplay.

Data can be retrieved in raw JSON format for you to parse on your own. Additionally, each of our SDKs provide methods for retrieving specific stats and data from a user’s profile. All data can be stored in dot notation for better organization of your profile data (e.g. data.stats.wins).

Updating Stats

You can update profiles by adding to a Commands object and calling one of our profile update functions.

  • AGCommand* commands = [[AGCommand alloc] init];
    [commands incValue:[NSNumber numberWithInt:1] forKey:@"data.stats.orbs_destroyed"];
    AGPromise* p = [client.myProfile updateModelWithCommands:commands];
    [p when:^(AGProfile* loadedProfile) {
       // ...
    }];
    
  • Commands commands = new Commands();
    commands.IncValue("data.stats.orbs_destroyed", 1);
    client.MyProfile.Update(commands, delegate(Request request)
    {
        // ...
    });
    
  • Commands commands = new Commands();
    commands.incValue("data.stats.orbs_destroyed", 1);
    client.getMyProfile().update(commands, new ObjectListener<Profile>() {
        @Override
        public void objectReceived(Profile profile, Response response) {
            // ...
        }
    });
    
  • Commands commands;
    commands.incValue("data.stats.orbs_destroyed", new Integer(1));
    client->getMyProfile()->update(c, [] (std::shared_ptr<Profile> profile, Request *request) {
        // ...
    });
    
  • Documentation coming soon.

Calculated Stats

Calculated stats are configured in the Profile Calculations section of the developer dashboard. See Calculated Stats for more information.

Reference: C++

Profile History

See Histories Documentation for details.

Reference Links:

  • Loading: C++ | REST </reference/studio/index.html#profiles__account_id__histories__interval_type_slug___date_>
  • Listing: C++ | REST </reference/studio/index.html#profiles__account_id__histories__interval_type_slug_>

Search Overview

See Search Documentation for more details.

Profile Search is comprised of Search Configurations and Saved Searches, both of which are configured through the dashboard. When writing field paths, start from the profile root. Examples:

  • account_id - The account_id for the profile
  • data.region - The profile’s region
  • aggregates.example.count - The number of sources that have been aggregated

User Segments

User segments use the Search functionality; however, segment definitions do not allow score or sort settings. They also cannot be configured to pull data from the logged-in user’s profile or the request body.

Whether or not a user is part of a segment is calculated at the time of the request. This allows you to set up a segment with a condition of “created_at greater than 1 month ago” and have players drop out of the segment as their account ages.

A user’s profile contains a list of slugs for the user segments they belong to at the time of the request.

Profile Notifications

You can send profile notifications to game clients under the following conditions:

  • From your game server, with a server API key, to all the registered devices of any profile.
  • From your game client, to all the registered devices of the logged in user.

This is useful for game servers if they need to notify clients of a server action. Or for game clients if they need to notify other devices of a user action.

Configuring

Profile notifications are based on templates that can be configured via the Hydra developer dashboard. From the dashboard:

  1. Select the Project and Environment that you would like to set up notifications for.
  2. Select Profile Services from the left sidebar (under Environment Config).
  3. Click the “Add notification” button. You are then presented with a list of options that you’ll need to configure.
  4. Once you save the template, it will be available for use during the game.
Identifier :
The identifier to be used by game clients to trigger the notification.
Contents :
The text that will go out over the notification systems. Can contain profile keys that will be substituted when sending out the notification.
Delivery types :
The systems that this notification should go out over. More documentation on notification delivery types can be found here.
Persistent :
Whether or not we should persist the notification if the user is not online.

Triggering

You can trigger a profile notification by using the advanced update endpoint. This endpoint allows you to provide the identifier of the notification template to use, as well as any extra data you want to send along with this update.

Reference: Unity | Android | C++ | REST

Receiving

The notification will go out over the configured delivery systems and trigger a Notified event for both the Profile and Profile Service objects in the SDKs.

Profile Leaderboards

See Leaderboards for more information.

Creating & Editing

Profile leaderboards are configurable within the Hydra developer dashboard. From the dashboard:

  1. Select the Project and Environment that you would like to set up the leaderboard for.
  2. Select Leaderboards from the left sidebar (under Environment Config).
  3. Click the “New leaderboard...” button. You are then presented with a list of options that you’ll need to configure.
  4. Once you save the leaderboard, it will start updating automatically based on the Profile stat it is tracking.
  5. At anytime, you can return to the Leaderboards page (steps 1 & 2 above) to edit an existing leaderboard. Click the edit button next to the leaderboard you want to change, and make your adjustments.

Code Examples

Standard

You can request the leaderboard with basic options.

  • AGLeaderboardOptions* options = [[AGLeaderboardOptions alloc] init];
    options.page = 1;
    options.fields = fields;
    AGPromise *p = [client.leaderboardService loadLeaderboard:leaderboardSlug options:options];
    [p when:^(NSArray* entries) {
        // ...
    }];
    
  • LeaderboardOptions options = new LeaderboardOptions().SetPage(0).SetFields(fields);
    client.Leaderboards.Show(leaderboardSlug, options, delegate(List<LeaderboardEntry> entries, Request request)
    {
        // ...
    });
    
  • LeaderboardOptions options = new LeaderboardOptions().setPage(0).setFields(fields);
    client.getLeaderboardsService().show(leaderboardSlug, options, new ObjectListListener<LeaderboardEntry>() {
        @Override
        public void objectReceived(List<LeaderboardEntry> entries, Response r) {
            // ...
        }
    });
    
  • LeaderboardOptions options = LeaderboardOptions().page(1).fields(fields);
    client->getLeaderboardService().show(leaderboardSlug, options, [] (std::vector<LeaderboardEntry> entries, Request *request) {
        // ...
    });
    
  • Documentation coming soon.

Friends only

You can request the leaderboard to be made up of only the accounts your user is following.

  • AGLeaderboardOptions* options = [[AGLeaderboardOptions alloc] init];
    options.page = 1;
    options.fields = fields;
    AGPromise *p = [client.leaderboardService loadLeaderboardAmongFriends:leaderboardSlug options:options];
    [p when:^(NSArray* entries) {
        // ...
    }];
    
  • LeaderboardOptions options = new LeaderboardOptions().SetPage(0).SetFields(fields);
    client.Leaderboards.Friends(leaderboardSlug, options, delegate(List<LeaderboardEntry> entries, Request request)
    {
        // ...
    });
    
  • LeaderboardOptions options = new LeaderboardOptions().setPage(0).setFields(fields);
    client.getLeaderboardsService().friends(leaderboardSlug, options, new ObjectListListener<LeaderboardEntry>() {
        @Override
        public void objectReceived(List<LeaderboardEntry> entries, Response r) {
            // ...
        }
    });
    
  • LeaderboardOptions options = LeaderboardOptions().page(1).fields(fields);
    client->getLeaderboardService().friends(leaderboardSlug, options, [] (std::vector<LeaderboardEntry> entries, Request *request) {
        // ...
    });
    
  • Documentation coming soon.

Around user

You can request the leaderboard to be pivoted around a specific user.

  • AGLeaderboardOptions* options = [[AGLeaderboardOptions alloc] init];
    options.page = 1;
    options.fields = fields;
    AGPromise *p = [client.leaderboardService loadLeaderboard:leaderboardSlug aroundPlayer:accountId options:options];
    [p when:^(NSArray* entries) {
        // ...
    }];
    
  • LeaderboardOptions options = new LeaderboardOptions().SetPage(0).SetFields(fields);
    client.Leaderboards.Around(leaderboardSlug, accountId, options, delegate(List<LeaderboardEntry> entries, Request request)
    {
        // ...
    });
    
  • LeaderboardOptions options = new LeaderboardOptions().setPage(0).setFields(fields);
    client.getLeaderboardsService().around(leaderboardSlug, options, new ObjectListListener<LeaderboardEntry>() {
        @Override
        public void objectReceived(List<LeaderboardEntry> entries, Response r) {
            // ...
        }
    });
    
  • LeaderboardOptions options = LeaderboardOptions().page(1).fields(fields);
    client->getLeaderboardService().around(leaderboardSlug, accountId, options, [] (std::vector<LeaderboardEntry> entries, Request *request) {
        // ...
    });
    
  • Documentation coming soon.

Table Of Contents

Previous topic

Relationships

Next topic

Profile Data Attachments