· 6 min read

Analytics In Swivel 2D (GameAnalytics Demo Game)

Our Head of Support Cristian Bercu built his own game to illustrate how simple it is to set up GameAnalytics with logical and efficient event tracking.

Introduction

Like any other software development team, the GameAnalytics SDK team invests time in team-building and in other activities that elevate the team spirit. We participated in a local game jam in late spring where we managed to imagine and implement a simple immersive game mechanic.

With a little more work after the event, we managed to build a simple game, which we later named Swivel 2D. The intention of building this small game is to illustrate how the GameAnalytics product can be used, from instrumentation through to the planning phase and finally on to programmatic implementation.

Download the game!

In order to fully understand the contents of this page, I’d recommend that you download and play the game. Here are the links:

Swivel is a pseudo-single player casual game for mobile platforms created by GameAnalytics with a minimal level design to show the usage of the tool’s main features. Unlike other drop-down games, Swivel compares your high-score against other players around the world. The target of the game is the GameAnalytics community of game developers.

Getting started with analytics

The environment used to develop the game is Unity and the C# programming language. However, this article depicts an instrumentation that can be reproduced in any other GameAnalytics supported development environment. You can find detailed setup guides for the GameAnalytics SDKs here.

Before implementing any custom instrumentation, I’d recommend that you first check to make sure the SDK runs and tracks core metrics (New Users, DAU and so on). In Unity, you only need to configure the SDK and create a GameAnalytics tracker in the very first scene of the game. Build and run the game and check the Real-time dashboard or the Live feed section in the Real-time dashboard to make sure events are being collected.

Design events

Swivel consists of 1.) a 3 step tutorial on how to play the game, 2.) an endless mode and 3.) a level based mode structured into 10 levels.

The game can be played by either tapping or swiping. The two mechanics in the game are introduced in the first two steps of the tutorial. In the third step, the player is asked: “Which one was better?”.

We are tracking the progression through the tutorial steps (and in a similar way the answer to the question) as follows:

 

Scene scene = SceneManager.GetActiveScene ();
GameAnalytics.NewDesignEvent("Tutorial:" + scene.name);

 

In the upper left corner of the screen there is a Skip button. Design events are used to track if users are skipping the tutorial and where, as follows:

 

Scene scene = SceneManager.GetActiveScene();
GameAnalytics.NewDesignEvent ("SkipTutorial:" + scene.name);

 

In the third step of the tutorial, the element of danger is introduced. We are tracking the explosion of the bomb in this level to understand how obvious it is to the human eye that the spiky rotating black balls are dangerous and to be avoided.

 

 

The analytics data helps to us understand if our players go through the tutorial steps, or if they drop along the way (and where).

In the endless run we track how far players get by using design events and the following formula:

For the first two rules for determining S, the formula drops the remainder of the score/segmentWidth division by casting it to an integer. In the end, we multiply it back by segmentWidth and we get the lower edge of the player score segment. If we sum the lower edge number with the segmentWidth we get the upper edge of the segment.

This is implemented using the following code:

if (score <= 100) 
{
    int segmentWidth = 10;
    int rezSegment = (score / segmentWidth) * segmentWidth; //operations with ints will lose the fractional part.
    GameAnalytics.NewDesignEvent ("Scores:" + rezSegment.ToString () + "-" + (rezSegment + segmentWidth).ToString ()); 
}
if (score > 100 && score <= 1000)
{
    int segmentWidth = 100;
    int rezSegment = (score / segmentWidth) * segmentWidth; //operations with ints will lose the fractional part.
    GameAnalytics.NewDesignEvent ("Scores:" + rezSegment.ToString () + "-" + (rezSegment + segmentWidth).ToString ()); 
}
if (score > 1000) 
{
    GameAnalytics.NewDesignEvent ("Scores:Over 1000");
}

When a player dies, they’re able to continue playing without losing progress by expensing one life. If the player runs out of lives they can exchange dots for lives. If they do not have enough dots they can either play more until they collect enough dots to exchange with lives, or they can directly purchase 2 lives worth of dots.

Business events

We are using Unity’s purchase system for managing transactions and our business events, with In-App purchase validation to track valid transactions.

public class Receipt {

	public string Store;
	public string TransactionID;
	public string Payload;

	public Receipt()
	{
		Store = TransactionID = Payload = "";
	}

	public Receipt(string store, string transactionID, string payload)
	{
		Store = store;
		TransactionID = transactionID;
		Payload = payload;
	}
}

public class PayloadAndroid
{
    public string json;
    public string signature;

    public PayloadAndroid()
    {
        json = signature = "";
    }

    public PayloadAndroid(string _json, string _signature)
    {
        json = _json;
        signature = _signature;
    }
}

public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs args)
{
if (String.Equals (args.purchasedProduct.definition.id, kProductIDConsumable, StringComparison.Ordinal)) {
    //...
    		var product = m_StoreController.products.WithID(kProductIDConsumable);
			string receipt = product.receipt;
			string currency = product.metadata.isoCurrencyCode;
			int amount = decimal.ToInt32 (product.metadata.localizedPrice) * 100;
#if UNITY_ANDROID
            Receipt receiptAndroid = JsonUtility.FromJson<Receipt>(receipt);
            PayloadAndroid receiptPayload = JsonUtility.FromJson<PayloadAndroid>(receiptAndroid.Payload);
            GameAnalytics.NewBusinessEventGooglePlay(currency, amount, "consumable", kProductIDConsumable, "vcCartType", receiptPayload.json, receiptPayload.signature);
#endif
#if UNITY_IPHONE
			Receipt receiptiOS = JsonUtility.FromJson<Receipt> (receipt);
			string receiptPayload = receiptiOS.Payload;
			GameAnalytics.NewBusinessEventIOS (currency, amount, "consumable", kProductIDConsumable, "vcCartType", receiptPayload);
#endif
}

Resource events

The player’s virtual currency fluctuations are tracked using resource events as follows:

//Dots
GameAnalytics.NewResourceEvent(GAResourceFlowType.Source,"Dots", settings.dots,"Collection", "Level" + currentLevel);
GameAnalytics.NewResourceEvent(GAResourceFlowType.Sink,"Dots", howMany * priceForLive,"Consumable","Exchange dots");
GameAnalytics.NewResourceEvent (GAResourceFlowType.Source, "Dots", 1, "Purchase", kProductIDConsumable);

//Lives
GameAnalytics.NewResourceEvent (GAResourceFlowType.Source, "Lives", howMany, "Consumable", "Exchange dots");
GameAnalytics.NewResourceEvent (GAResourceFlowType.Sink, "Lives", 1, "Consumable", "Level " + lm.currentLevel);

Progression events

The game allows the player to experience an arcade mode by playing 10 predefined levels. To start playing the levels you need to select “Play Arcade” from the drop-down menu in the upper right corner. The first level loads and if you press on the drop-down button once more the following screen is displayed:

 

The schema for instrumenting progression events with all of the levels is as follows:

The player’s progression is tracked programmatically with GameAnalytics as follows:

if (currentLevel < 10) {
    GameAnalytics.NewProgressionEvent (GAProgressionStatus.Complete, "Level 0" + currentLevel,settings.score);
} else {
    GameAnalytics.NewProgressionEvent (GAProgressionStatus.Complete, "Level " + currentLevel,settings.score);
}

That’s all folks!

I hope that this demonstration of a simple analytics instrumentation is valuable to all of our readers. We’re eager to see more of you great devs instrumenting your games with GameAnalytics! The analytics results will be added as soon as there is enough data to depict consistent metrics. ?