Select Assets -> Import Package -> Custom Package, then browse to where the Playtomic.unitypackage is where you unzipped the file.
The first thing you must do is initialize the API. Without doing this none of the services will work:
Playtomic.Initialize(gameid, "guid", "apikey");
After doing that log the view. If your game is mobile then do this when the application opens or resumes:
Playtomic.Log.View();
Premium users can use SSL for all API communication by calling this method after initializing the API but before logging the view:
Playtomic.SetSSL();
A view occurs whenever somebody views your game. This should go somewhere very early in your code like before the preloader. If you are making mobile/tablet games then you will want to do this when the application resumes as well.
Playtomic.Log.View();
Note: We are currently changing the naming to Sessions as it is more appropriate today. Changes will be applied in next API version.
This occurs wherever you feel a player has become engaged in your game. It's subjective, previously we recommended putting it on the play button but that is less suitable in a mobile environment so you should use this at some point early in your game where you feel a player has decided to really play your game rather than open it.
Note: We are currently changing the naming to Engages. Changes will be applied in next API version.This data is logged automatically when you send other events.
Playtomic.Log.Play();
Note: This is inherited from the Flash version which runs on a single thread, and is unlikely to be necessary in Unity games.
Events are sent in batches each time the play timer updates (every 30 seconds after the first minute). If you want to ensure an event gets sent:
Playtomic.Log.ForceSend();
Some games are very resource-intensive and the API might send off a batch of events at exactly the wrong time. You can freeze and unfreeze the logging at any time by:
Playtomic.Log.Freeze();
Playtomic.Log.UnFreeze();
When logging is frozen all events are queued but not sent until you unfreeze the API.
Custom metrics allow you to track how many people do something in your game, for instance how many play on easy, medium or hard, or how many play in English vs. Spanish, or how many view the tutorial or skip it. Anything you think can help you improve your game.
You can define custom metrics directly in your game and they will be added to Playtomic automatically. Groups can be automatically assigned via an optional second parameter or set up later in the dashboard.
You can also limit custom metrics to unique-per-view occurances with a third parameter.
Playtomic.Log.CustomMetric("ViewedCredits"); // metric, names must be alphanumeric
Playtomic.Log.CustomMetric("Credits", "Screens"); // metric with group, groups must be alphanumeric
Playtomic.Log.CustomMetric("ClickedSponsorsLink", "Links", true); // unique metric with group
Level metrics track events on a per-level basis so you can drill down into your difficulty and retention by identifying which levels have problems and what those problems are.
There are three types of level metrics - counters (like custom metrics), ranged-value and average-value.
Note that you can pass either an integer level number or a string name of the level. If your game is not using numeric levels (eg an escape game) then you would pass the name of each screen / area as a level.
You can define level metrics directly in your game and they will be added to Playtomic automatically.
Level metrics support unique-per-play occurrances via an optional second parameter. If the player starts a new game they will be tracked again.
These metrics track how many times something occurs in your levels, for instance deaths and restarts.
One of the most valuable pieces of data you can track is how many people begin each level, this allows you to see where you lose players.
Playtomic.Log.LevelCounterMetric("Deaths", level_number); // names must be alphanumeric
Playtomic.Log.LevelCounterMetric("Restarts", "LevelName"); // level names must be alphanumeric
Playtomic.Log.LevelCounterMetric("Restarts", "LevelName", true); // unique only
These metrics track the average of something in your levels, for instance the average time to finish a level or the average number of retries. It also tracks the minimum and maximums.
Playtomic.Log.LevelAverageMetric("Time", level_number, seconds);
Playtomic.Log.LevelAverageMetric("Retries", level_number, retries);
Playtomic.Log.LevelAverageMetric("Retries", level_number, retries, true); // unique only
These metrics track metrics with values, for instance in a golf game you might track how many shots it takes to complete each level, or you might track the % of coins collected on each level.
Playtomic.Log.LevelRangedMetric("Shots", level_number, shots);
Playtomic.Log.LevelRangedMetric("PercentCoinsCollected", level_number, int(coins / coinstotal * 100));
Playtomic.Log.LevelRangedMetric("Shots", level_number, shots, true); // unique only
Heatmaps allow you to map activity (clicks, deaths, first deaths, or anything else you want) against an image you upload in the dashboard.
Playtomic.Log.Heatmap("Metric", "Heatmap", x, y);
In the dashboard you upload a background image for the heatmap, and then it is shared by any metrics using it.
Referrers allow you to track who has referrered your game.
Playtomic.Log.SetReferrer("Referrer");
Link tracking allows you to keep track of how many people open URLs in your game, providing you information on unique, total and failed clicks that can fully audited to allow you to identify good sources of traffic.
Link tracking does not change your URL or redirect traffic through a different url!
You track a link by passing a URL and some other information to the API. The API will return true or false (not implemented yet) if the link opens, everything else is automatic.
Playtomic.Link.Open(url, name, group);
Playtomic.Link.Open("http://website.com/", "Website", "MyLinks");
When you track a link it automatically also tracks the totals for the domain in a group it creates called DomainTotals. The DomainTotals allows you to see how many unique, total and failed clicks occurred for a single domain even if you have multiple, different links to it (eg walkthrough or differently-structured sponsor links).
This feature is provided in conjunction with Parse so you will need to create your account with them before you can use it.
Custom databases allow you to store and manipulate any data you want in any way you want, like:
This object represents a piece of data in your database. It has the following properties:
| Property | Type | Description |
|---|---|---|
| ObjectId | String | If your object already exists in your database it will have this unique identifier. |
| ClassName | String | The 'type' of data this is - user, score, etc |
| Data | Dictionary<String, String> | Your actual data to save, eg po.Data.FirstName. The 'fields' in your data must be valid variable names / object properties. |
| UpdatedAt | DateTime | When the object was last updated in the database |
| CreatedAt | DateTime | When the object was created in the database |
| Password | String | If an object has a password when it is saved the password must be included to update it. |
This object allows you to construct a query to run against your database to find objects you've saved.
| Property | Type | Description |
|---|---|---|
| ClassName | String | The 'type' of data to return - user, score, etc |
| WhereData | Dictionary<String, String> | Data to filter by, eg pq.WhereData.FirstName = 'ben' |
| Order | String | What field (from Data) to sort by |
| Limit | int | Numner of results to return |
You can save any object you want by creating a PFObject and sending it to Parse.Save. An object will save if it does not have an ObjectId, if it does then it will update.
StartCoroutine(SaveParseObject());
IEnumerator SaveParseObject()
{
var po = new PFObject();
po.ClassName = "savedgames";
po.Data.Add("Name", "Ben");
po.Data.Add("Level", "1");
po.Data.Add("Stage", "7");
yield return StartCoroutine(Playtomic.Parse.Save(po));
var response = Playtomic.Parse.GetResponse("Save");
if(response.Success)
{
Debug.Log("Object saved: " + response.PObject.ObjectId);
}
else
{
Debug.Log("Object failed to save because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// js
function SaveParseObject()
{
var po = new PFObject();
po.ClassName = "savedgames";
po.Data.Add("Name", "Ben");
po.Data.Add("Level", "1");
po.Data.Add("Stage", "7");
yield StartCoroutine(Playtomic.Parse.Save(po));
var response = Playtomic.Parse.GetResponse("Save");
if(response.Success)
{
Debug.Log("Object saved: " + response.PObject.ObjectId);
}
else
{
Debug.Log("Object failed to save because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
You can load any object as long as you know it's ClassName and ObjectId (which you might obtain from a PFPointer).
StartCoroutine(LoadParseObject());
IEnumerator LoadParseObject()
{
yield return StartCoroutine(Playtomic.Parse.Load("classname", "objectid"));
var response = Playtomic.Parse.GetResponse("Load");
if(response.Success)
{
var po = response.PObject;
// do whatever
Debug.Log("Object loaded: " + response.PObject.ObjectId);
}
else
{
Debug.Log("Object failed to load because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// js
function LoadParseObject()
{
yield StartCoroutine(Playtomic.Parse.Load("classname", "objectid"));
var response = Playtomic.Parse.GetResponse("Load");
if(response.Success)
{
var po = response.PObject;
// do whatever
Debug.Log("Object loaded: " + response.PObject.ObjectId);
}
else
{
Debug.Log("Object failed to load because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
Using the PFQuery object you can locate data in your database:
StartCoroutine(FindParseObject());
IEnumerator FindParseObject()
{
var pq = new PFQuery();
pq.ClassName = "savedgames";
yield return StartCoroutine(Playtomic.Parse.Find(pq));
var response = Playtomic.Parse.GetResponse("Find");
if(response.Success)
{
Debug.Log("Objects found: " + response.PObjects.Count);
for(var i=0; i<response.PObjects.Count; i++)
Debug.Log(response.PObjects[i].ObjectId);
}
else
{
Debug.Log("Object failed to find because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// js
function FindParseObject()
{
var pq = new PFQuery();
pq.ClassName = "savedgames";
yield StartCoroutine(Playtomic.Parse.Find(pq));
var response = Playtomic.Parse.GetResponse("Find");
if(response.Success)
{
Debug.Log("Objects found: " + response.PObjects.length);
for(var i=0; i<response.PObjects.length; i++)
Debug.Log(response.PObjects[i].ObjectId);
}
else
{
Debug.Log("Object failed to find because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
You can delete an object as long as you know the ClassName and ObjectId.
StartCoroutine(DeleteParseObject(po));
IEnumerator DeleteParseObject(PFObject po)
{
yield return StartCoroutine(Playtomic.Parse.Delete(po));
var response = Playtomic.Parse.GetResponse("Delete");
if(response.Success)
{
Debug.Log("Deleted object");
}
else
{
Debug.Log("Failed to delete: " + response.ErrorMessage);
}
}
// js
function DeleteParseObject(PFObject po)
{
yield StartCoroutine(Playtomic.Parse.Delete(po));
var response = Playtomic.Parse.GetResponse("Delete");
if(response.Success)
{
Debug.Log("Deleted object");
}
else
{
Debug.Log("Failed to delete: " + response.ErrorMessage);
}
}
The level sharing API provides a way to store and retrieve user-generated content for your game. It can operate anonymously or authenticated via any 3rd party service you're already using.
All parts of the API that return data to you do it via a response object. The response object tells you if the request succeeded, why it failed, and contains any data you requested.
For all requests that return data you receive the respones via:
var response = Playtomic.API_PART.GetResponse("METHOD");
The relevant parts of the Response object for level sharing are:
| Property | Type | Description |
|---|---|---|
| Success | Boolean | Tells you whether the request succeeded. |
| ErrorCode | int | The numeric reason the error failed (see errorcode tables here in the documentation) |
| ErrorDescription | String | The reason the error failed |
| Name | String | The name of the level |
| NumItems | int | The number of levels if you requested a list |
| Levels | Array | Collection of levels if you requested a list |
Saving and listing levels uses this class to represent a level.
| Property | Type | Description |
|---|---|---|
| PlayerName | String | The name of the player (or "anonymous", "guest", etc), or the name provided by any 3rd party API. |
| PlayerId | String | If you're working under a 3rd party API you can include the player's user id |
| PlayerSource | String | If you're working under a 3rd party API you can specify which, eg "gamersafe" or "mochicoins" |
| Name | String | The name of the level |
| Data | String | The data for the level. You can Base 64 encode a ByteArray to a string if necessary. |
| Votes | int | The number of votes the level has |
| Score | int | The sum of all votes the level has |
| Rating | double | The rating the level has (score / votes) |
| SDate | Date | The date of the level, determined automatically by Playtomic |
| RDate | String | The relative date of the level eg "7 minutes ago", determined automatically by Playtomic |
| CustomData | Dictionary | Any additional data you want to (or have) attached to a level. |
| Thumbnail | Func, ret. string | The URL of the thumbnail, unless you generate them from data (recommended) |
| Starts | int | The number of times the level has been started |
| Wins | int | The number of times the level has been won |
| Quits | int | The number of times the level has been quitted |
| Retries | int | The number of times the level has been retried |
| Flags | int | The number of times the level has been flagged |
yield return StartCoroutine(Playtomic.PlayerLevels.Save(level));
var response = Playtomic.PlayerLevels.GetResponse("Save");
Example saving level:
// C#
IEnumerator MySaveFunction()
{
var level = new Playtomic_PlayerLevel();
level.Name = this is a level";
level.PlayerName = "Ben";
level.Data = "Asdfasdfasdfasdf";
yield return StartCoroutine(Playtomic.PlayerLevels.Save(level));
var response = Playtomic.PlayerLevels.GetResponse("Save");
if(response.Success)
{
Debug.Log("Level saved!");
}
else
{
Debug.Log("Level failed to save because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function MySaveFunction()
{
var level = new Playtomic_PlayerLevel();
level.Name = "this is a level";
level.PlayerName = "Ben";
level.Data = "Asdfasdfasdfasdf";
yield StartCoroutine(Playtomic.PlayerLevels.Save(level));
var response = Playtomic.PlayerLevels.GetResponse("Save");
if(response.Success)
{
Debug.Log("Level saved!");
}
else
{
Debug.Log("Level failed to save because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
Levels can be rated 1 - 10 by players. Rating can be done anonymously with some protection against repeat voting, or bound to PlayerIds if you specify them.
Playtomic.PlayerLevels.Rate(levelid, rating)
Example rating level:
// C#
IEnumerator RateLevel()
{
yield return StartCoroutine(Playtomic.PlayerLevels.Rate("4d8930441ea37f0a34002993", 8));
var response = Playtomic.PlayerLevels.GetResponse("Rate");
if(response.Success)
{
Debug.Log("Level rated successfully");
}
else
{
Debug.Log("Level rating failed because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function RateLevel()
{
yield StartCoroutine(Playtomic.PlayerLevels.Rate("4d8930441ea37f0a34002993", 8));
var response = Playtomic.PlayerLevels.GetResponse("Rate");
ifresponse.Success)
{
Debug.Log("Level rated successfully");
}
else
{
Debug.Log("Level rating failed because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
Listing levels can be done by popular or newest, with optional filtering by date ranges and (not yet implemented: custom data).
Playtomic.PlayerLevels.List(mode, page, perpage);
Playtomic.PlayerLevels.List(mode, page, perpage, includedata, includethumbs);
Playtomic.PlayerLevels.List(mode, page, perpage, includedata, includethumbs, datemin, datemax);
| Parameter | Type | Description |
|---|---|---|
| mode | String | popular or newest |
| page | int | 1, or calculate it with your own pagination |
| perpage | int | Number of levels to return per request |
| includedata | bool | Return level data with the request, alternatively load level data seperately |
| includethumbs | bool | Return thumbnails with the request (not implemented), alternatively load from url |
| datemin | DateTime | Minimum date the level was created |
| datemax | DateTime | Maximum date the level was created |
An example listing levels:
// C#
IEnumerator ListLevels()
{
yield return StartCoroutine(Playtomic.PlayerLevels.List("popular", 1, 10));
var response = Playtomic.PlayerLevels.GetResponse("List");
ifresponse.Success)
{
Debug.Log("Levels listed successfully: " + response.NumItems + " in total, " + response.Levels.Count + " returned");
foreach(var level in response.Levels)
{
Debug.Log(" - " + level.LevelId + ": " + level.Name);
}
}
else
{
Debug.Log("Level list failed to load because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function ListLevels()
{
yield StartCoroutine(Playtomic.PlayerLevels.List("popular", 1, 10));
var response = Playtomic.PlayerLevels.GetResponse("List");
if(response.Success)
{
Debug.Log("Levels listed successfully: " + response.NumItems + " in total, " + response.Levels.Count + " returned");
for(var i=0; i<response.Levels.Count; i++)
{
var level = response.Levels[i];
Debug.Log(" - " + level.LevelId + ": " + level.Name);
}
}
else
{
Debug.Log("Level list failed to load because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
If you do not include the data when you load lists of levels then you can request it seperately:
Playtomic.PlayerLevels.Load(levelid);
An example loading a single level
// C#
IEnumerator LoadLevel()
{
yield return StartCoroutine(Playtomic.PlayerLevels.Load("xxxxxxxx"));
var response = Playtomic.PlayerLevels.GetResponse("Load");
if(response.Success)
{
Debug.Log("Level loaded successfully: ");
var level = response.Levels[0];
Debug.Log(" - " + level.LevelId + ": " + level.Name + ""\n" + level.Data);
}
else
{
Debug.Log("Level failed to load because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function LoadLevel()
{
yield StartCoroutine(Playtomic.PlayerLevels.Load("xxxxxxxxxxx"));
var response = Playtomic.PlayerLevels.GetResponse("Load");
if(response.Success)
{
Debug.Log("Level loaded successfully: ");
var level = response.Levels[0];
Debug.Log(" - " + level.LevelId + ": " + level.Name + "\n" + level.Data);
}
else
{
Debug.Log("Level failed to load because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
The leaderboards API gives you very flexible high and low score leaderboards. They can be created in your game dynamically or set up in the edit leaderboards page.
All parts of the API that return data to you do it via a response object. The response object tells you if the request succeeded, why it failed, and contains any data you requested.
For all requests that return data you receive the respones via:
var response = Playtomic.API_PART.GetResponse("METHOD");
The relevant parts of the Response object for leaderboards are:
| Property | Type | Description |
|---|---|---|
| Success | Boolean | Tells you whether the request succeeded. |
| ErrorCode | int | The numeric reason the error failed (see errorcode tables here in the documentation) |
| ErrorDescription | String | The reason the error failed |
| Name | String | The name of the level |
| NumItems | int | The number of levels if you requested a list |
| Scores | Array | Collection of scores if you requested a list |
The leaderboards use the PlayerScore object for representing the players' scores.
| Property | Type | Description |
|---|---|---|
| Name | String | The player name. This can be by the player or provided by any 3rd party |
| FBUserId | String | If you're working with Facebook scores specify the player's user id |
| Points | Number | The player's score |
| Rank | int | The player's rank on the leaderboards, determined by the listing options you send |
| Website | String | The website the score occurred on, determined automatically by Playtomic |
| SDate | Date | The date of the score, determined automatically by Playtomic |
| RDate | String | The relative date of the score eg "7 minutes ago", determined automatically by Playtomic |
| CustomData | Dictionary | Any additional data you want to (or have) attached to a score, like the level the player reached or what character they used |
Score submission is handled by:
Playtomic.Leaderboards.Save(table, score, highest);
Playtomic.Leaderboards.Save(table, score, highest, allowduplicates);
Playtomic.Leaderboards.Save(table, score, highest, allowduplicates, facebook);
| Parameter | Type | Description |
|---|---|---|
| score | PlayerScore | An instance of PlayerScore which contains score information |
| table | String | The score table to submit to, alphanumeric |
| highest | bool | Set the leaderboard mode in case it's the first request and has to be created |
| allowduplicates | bool | Allow the same player to submit multiple scores |
| bool | Make this a Facebook score (remember to set the score's FBUserId) |
// C#
IEnumerator SaveScore()
{
var score = new Playtomic_PlayerScore();
score.Name = "Ben";
score.Points = 1000000;
yield return StartCoroutine(Playtomic.Leaderboards.Save("highscores", score, true));
var response = Playtomic.PlayerLevels.GetResponse("Save");
if(response.Success)
{
Debug.Log("Score saved!");
}
else
{
Debug.Log("Score failed to save because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function SaveScore()
{
var score = new Playtomic_PlayerScore();
score.Name = "Ben";
score.Points = 1000000;
yield StartCoroutine(Playtomic.Leaderboards.Save("highscores", score, true));
var response = Playtomic.PlayerLevels.GetResponse("Save");
if(response.Success)
{
Debug.Log("Score saved!");
}
else
{
Debug.Log("Score failed to save because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
Scores are loaded via a simple method that returns an array of PlayerScore objects to your function where you can display the data in your leaderboard.
Playtomic.Leaderboards.List(table, highest, mode, page, perpage);
Playtomic.Leaderboards.List(table, highest, mode, page, perpage, customfilters);
Playtomic.Leaderboards.List(table, highest, mode, page, perpage, customfilters, facebook, friendslist);
| Parameter | Type | Description |
|---|---|---|
| table | String | Your leaderboard table name |
| highest | bool | If this is the leaderboard needs to be created this will set the mode |
| mode | string |
|
| page | int | 1 or calculate it with your pagination |
| perpage | int | Number of scores to return |
| customfilters | Dictionary | If you attach custom data to your scores you can filter by it |
| Boolean | Set to true if your game is on Facebook | |
| friendslist | string[] | Array of friends user ids for Facebook leaderboards, to show scores from you and your friends. |
// C#
IEnumerator ListScores()
{
yield return StartCoroutine(Playtomic.Leaderboards.List("highscores", true, "alltime", 1, 20));
var response = Playtomic.Leaderboards.GetResponse("List");
if(response.Success)
{
Debug.Log("Scores listed successfully: " + response.NumItems + " in total, " + response.Scores.Count + " returned");
for(var i=0; i<response.Scores.Count; i++)
Debug.Log(response.Scores[i].Name + ": " + response.Scores[i].Points);
}
else
{
Debug.Log("Score list failed to load because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function ListScores()
{
yield StartCoroutine(Playtomic.Leaderboards.List("highscores", true, "alltime", 1, 20));
var response = Playtomic.Leaderboards.GetResponse("List");
if(response.Success)
{
Debug.Log("Scores listed successfully: " + response.NumItems + " in total, " + response.Scores.Count + " returned");
for(var i=0; i<response.Scores.Count; i++)
Debug.Log(response.Scores[i].Name + ": " + response.Scores[i].Points);
}
else
{
Debug.Log("Score list failed to load because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
You can now submit scores and at the same time return the leaderboard page that that score is on.
This combines the Save and List approaches from above:
Playtomic.Leaderboards.SaveAndList(string table, Playtomic_PlayerScore score, bool highest, string mode, int perpage, bool isglobal)
Playtomic.Leaderboards.SaveAndList(string table, Playtomic_PlayerScore score, bool highest, string mode, int perpage, bool isglobal, bool allowduplicates)
Playtomic.Leaderboards.SaveAndList(string table, Playtomic_PlayerScore score, bool highest, string mode, int perpage, bool isglobal, bool allowduplicates, bool facebook, Dictionary<String, String> customfilters)
Some important notes:
// C#
var score = new Playtomic_PlayerScore();
score.Name = "Ben";
score.Points = 1000000;
IEnumerator SaveAndListScores()
{
yield return StartCoroutine(Playtomic.Leaderboards.SaveAndList(score, "highscores", true, "alltime", 1, 20));
var response = Playtomic.Leaderboards.GetResponse("SaveAndList");
if(response.Success)
{
Debug.Log("Scores listed successfully: " + response.NumItems + " in total, " + response.Scores.Count + " returned");
for(var i=0; i<response.Scores.Count; i++)
Debug.Log(response.Scores[i].Name + ": " + response.Scores[i].Points);
}
else
{
Debug.Log("Score failed to save or failed to list because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
var score = new Playtomic_PlayerScore();
score.Name = "Ben";
score.Points = 1000000;
function ListScores()
{
yield StartCoroutine(Playtomic.Leaderboards.SaveAndList(score, "highscores", true, "alltime", 1, 20));
var response = Playtomic.Leaderboards.GetResponse("SaveAndList");
if(response.Success)
{
Debug.Log("Scores listed successfully: " + response.NumItems + " in total, " + response.Scores.Count + " returned");
for(var i=0; i<response.Scores.Count; i++)
Debug.Log(response.Scores[i].Name + ": " + response.Scores[i].Points);
}
else
{
Debug.Log("Score failed to save or failed to list because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
You can now provide your players the ability to create their own leaderboard complete with a permalink and shortened URL they can give their friends to compete against each other.
Note: The permalink is going to append the leaderboard table's id, it should be like "http://site.com/game/?leaderboard=" or http://site.com/game?something=whatever&leaderboard=
Creating a leaderboard is simply:
Playtomic.Leaderboards.CreatePrivateLeaderboard(name, highest, permalink, callback);
// C#
IEnumerator CreateMyLeaderboard()
{
yield return StartCoroutine(Playtomic.Leaderboards.CreatePrivateLeaderboard("leaderboardname", "http://mysponsorsite.com/mygame?leaderboard=", highest));
var response = Playtomic.Leaderboards.GetResponse("CreatePrivateLeaderboard");
if(response.Success)
{
Debug.Log("Leaderboard created correctly: ");
Debug.Log(response.GetData("Name"));
Debug.Log(response.GetData("RealName"));
Debug.Log(response.GetData("Permalink"));
Debug.Log(response.GetData("Bitly"));
}
else
{
Debug.Log("Failed to create leaderboard because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function CreateMyLeaderboard()
{
yield StartCoroutine(Playtomic.Leaderboards.CreatePrivateLeaderboard("leaderboardname", "http://mysponsorsite.com/mygame?leaderboard=", highest));
var response = Playtomic.Leaderboards.GetResponse("CreatePrivateLeaderboard");
if(response.Success)
{
Debug.Log("Leaderboard created correctly: ");
Debug.Log(response.GetData("Name"));
Debug.Log(response.GetData("RealName"));
Debug.Log(response.GetData("Permalink"));
Debug.Log(response.GetData("Bitly"));
}
else
{
Debug.Log("Score failed to save or failed to list because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
function CreateComplete(response)
{
if(response.Success)
{
Debug.Log(response.Name);
Debug.Log(response.Permalink); // full link, eg sponsorwebsite.com/play/my/game?leaderboard=asdfasfasdfasdf
Debug.Log(response.Bitly); // bitly link to their leaderboard, eg bitly.com/blabla
Debug.Log(response.Highest);
Debug.Log(response.RealName); // internally used guaranteed unique name: user_RANDOMSTUFF_the name they provided
}
else
{
// leaderboard failed to save because of response.ErrorCode
}
}
When a person visits either the Permalink or the shortened Bitly link you can make them use that leaderboard by:
var leaderboardid = Leaderboards.GetLeaderboardFromUrl();
if(leaderboardid != null)
{
Leaderboards.Load(leaderboardid, this.PrivateLeaderboardLoaded);
}
function PrivateLeaderboardLoaded(response)
{
Debug.Log(response.Name);
Debug.Log(response.Permalink);
Debug.Log(response.Bitly);
Debug.Log(response.Highest);
Debug.Log(response.RealName);
}
When you save scores on a private leaderboard you must use the RealName, not the Name.
This has now been integrated directly with the regular Listing. Check the facebook and friendslist parameters on the Leaderboards.List above.
Scores are no longer available directly via URL as they expect POST data now. You will need to use the HTML5 / JavaScript API for showing scores on your web page, or the Flash or other APIs for embedding them in a SWF or other container.
GameVars let you change the value of key variables in your game any time you want. They must be configured on the edit GameVars page in advance.
It is called via:
Playtomic.GameVars.Load();
You can load variables individually, for instance if you are caching the GameVars you can check a 'version' GameVar to decide whether to reload the full collection.
Playtomic.GameVars.LoadSingle("name");
// C#
IEnumerator LoadGameVars()
{
yield return StartCoroutine(Playtomic.GameVars.Load());
var response = Playtomic.GameVars.GetResponse("Load");
// or
yield return StartCoroutine(Playtomic.GameVars.LoadSingle("version"));
var response = Playtomic.GameVars.GetResponse("LoadSingle");
if(response.Success)
{
Debug.Log("GameVars are loaded!");
foreach(var key in response.Data.Keys)
{
Debug.Log("GameVar '" + key + "' = '" + response.Data[key]);
}
// alternatively
// response.GetValue("version");
}
else
{
Debug.Log("GameVars failed because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function LoadGameVars()
{
yield StartCoroutine(Playtomic.GameVars.Load());
var response = Playtomic.GameVars.GetResponse("Load");
if(response.Success)
{
Debug.Log("GameVars are loaded!");
for(var key in response.Data)
{
Debug.Log("GameVar " + key + " = " + response.Data[key]);
}
// alternatively
// response.GetValue("varname");
}
else
{
Debug.Log("GameVars failed because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
The GeoIP service identifies which country the player is from, returning their country code and name.
It is called via:
Playtomic.GeoIP.Lookup();
// C#
IEnumerator LoadGeoIP()
{
Debug.Log("Loading GeoIP lookup");
yield return StartCoroutine(Playtomic.GeoIP.Lookup());
var response = Playtomic.GeoIP.GetResponse("Lookup");
if(response.Success)
{
Debug.Log("Country is: " + response.GetValue("Code") + " - " + response.GetValue("Name"));
}
else
{
Debug.Log("Lookup failed because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function LoadGeoIP()
{
Debug.Log("Loading GeoIP lookup");
yield StartCoroutine(Playtomic.GeoIP.Lookup());
var response = Playtomic.GeoIP.GetResponse("Lookup");
if(response.Success)
{
Debug.Log("Country is: " + response.GetValue("Code") + " - " + response.GetValue("Name"));
}
else
{
Debug.Log("Lookup failed because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
Note: You must enable this functionality in each game's settings. By default it is disabled becaue it can expose your game Playtomic.Data.
The Data class in the API allows you to retrieve any of your game data to display in your game.
Each function for retrieving data takes an optional parameters object for day, month and year, with default values of 0.
The Views, Plays and PlayTime functions returns this data to you for processing:
Playtomic.Data.Views(); // total
Playtomic.Data.Views(month, year); // value for month
Playtomic.Data.Views(day, month, year); // value on day
Playtomic.Data.Plays();
Playtomic.Data.Plays(month, year);
Playtomic.Data.Plays(day, month, year);
Playtomic.Data.PlayTime();
Playtomic.Data.PlayTime(month, year);
Playtomic.Data.PlayTime(day, month, year);
When you perform a Data lookup the values are returned in a dictionary. These methods have:
// C#
IEnumerator LoadData()
{
yield return StartCoroutine(Playtomic.Data.Views());
var response = Playtomic.Data.GetResponse("Views");
if(response.Success)
{
Debug.Log("Data API returned " + response.GetValue("Value"));
}
else
{
Debug.Log("Lookup failed because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
// JS
function LoadData()
{
yield StartCoroutine(Playtomic.Data.Views());
var response = Playtomic.Data.GetResponse("Views");
if(response.Success)
{
Debug.Log("Data API returned " + response.GetValue("Value"));
}
else
{
Debug.Log("Lookup failed because of " + response.ErrorCode + ": " + response.ErrorDescription);
}
}
The CustomMetric function returns data about a custom metric to your function, which receives the same parameters as views/plays/play time above.
Playtomic.Data.CustomMetric(name);
Playtomic.Data.CustomMetric(name, month, year);
Playtomic.Data.CustomMetric(name, day, month, year);
Available keys are:
There are three methods for retrieving level metrics. The functions that receive the data are different from the above examples.
Playtomic.Data.LevelCounterMetric(name, level);
Playtomic.Data.LevelRangedmetric(name, level, month, year);
Playtomic.Data.LevelAverageMetric(name, level, day, month, year);
Available keys are:
When a Playtomic service is unreachable or has an error it will return a numeric error code. This table describes those errors:
These errors may be returned from any service.
| Code | Meaning |
|---|---|
| 0 | No error |
| 1 | General error, this typically means the player is unable to connect to the Playtomic servers |
| 2 | Invalid game credentials. Make sure you use your SWFId and GUID from the "API" section in the dashboard. |
| 3 | Request timed out. |
| 4 | Invalid request. This means the request wasn't formed right, probably because the API key wasn't provided or was incorrect. |
| Code | Meaning |
|---|---|
| 100 | GeoIP API has been disabled. This may occur if your game is faulty or overwhelming the Playtomic servers. |
| Code | Meaning |
|---|---|
| 200 | Leaderboard API has been disabled. This may occur if your game is faulty or overwhelming the Playtomic servers. |
| 201 | The source URL or name weren't provided when saving a score. Make sure the player specifies a name and the game is initialized before anything else using the code in the "Set your game up" section. |
| 202 | Invalid auth key. You should not see this normally, players might if they tamper with your game. |
| 203 | No Facebook user id on a score specified as a Facebook submission. |
| 204 | Table name wasn't specified for creating a private leaderboard. |
| 205 | Permalink structure wasn't specified: http://website.com/game/whatever?leaderboard= |
| 206 | Leaderboard id wasn't provided loading a private leaderboard. |
| 207 | Invalid leaderboard id was provided for a private leaderboard. |
| 208 | Player is banned from your leaderboard. |
| 209 | SaveAndList only. The score was not the player's best score. You can message the player, highlight their best via the SubmittedOrBest boolean property of scores, or override this by setting allowduplicates to true. |
| Code | Meaning |
|---|---|
| 300 | GameVars API has been disabled. This may occur if your game is faulty or overwhelming the Playtomic servers. |
| Code | Meaning |
|---|---|
| 400 | Level sharing API has been disabled. This may occur if your game is faulty or overwhelming the Playtomic servers. |
| 401 | Invalid rating value (must be 1 - 10). |
| 402 | Player has already rated that level. |
| 403 | The level name wasn't provided when saving a level. |
| 404 | Invalid image auth. You should not see this normally, players might if they tamper with your game. |
| 405 | Invalid image auth (again). You should not see this normally, players might if they tamper with your game. |
| 406 | The level already exists. This is determined via a hash of the game id, level name, player ip address and name, and source url. |
| Code | Meaning |
|---|---|
| 500 | Data API has been disabled. This may occur if the Data API is not enabled for your game, or your game is faulty or overwhelming the Playtomic servers. |
| Code | Meaning |
|---|---|
| 600 | You have not configured your Parse.com database. Sign up at Parse and then enter your API credentials in your Playtomic dashboard. |
| 601 | No response was returned from Parse. If you experience this a lot let us know exactly what you're doing so we can sort out a fix for it. |
| 6021 | Parse's servers had an error. |
| 602101 | Object not found. Make sure you include the classname and objectid and that they are correct. |
| 602102 | Invalid query. If you think you're doing it right let us know what you're doing and we'll look into it. |
| 602103 | Invalid classname. |
| 602104 | Missing objectid. |
| 602105 | Invalid key name. |
| 602106 | Invalid pointer. |
| 602107 | Invalid JSON. |
| 602108 | Command unavailable. |
Friends, Playtomic has come to an end. Part of this service will live on at Playtomic.org as a self-hosted, open source platform I am continuing to develop in my spare time. The rest is unfortunately finished.
Enter your email and we'll send you your views data.