Event Tracking
GameAnalytics features the following event types:
Event | Description |
---|---|
Ad | Ads shown and clicked, fill rate. |
Business | In-App Purchases supporting receipt validation on GA servers. |
Design | Submit custom event id’s. Useful for tracking metrics specifically needed for your game. |
Error | Submit exception stack traces or custom error messages. |
Health | Automatically submits health metrics related to your game such as FPS. |
Impression | Impression data from different ad networks |
Progression | Level attempts with Start, Fail & Complete event. |
Resource | Managing the flow of virtual currencies - like gems or lives |
Read more about events here
Event id’s are strings separated by colons defining an event hierarchy – like “kill:robot:large”. It is important to not generate an excessive amount of unique nodes possible in the event hierarchy tree.
A bad implementation example: [level_name]:[weapon_used]:[damage_done]
level_name could be 100 values, weapon_used could be 300 values and damage_done could be 1-5000 perhaps. This will generate an event hierarchy with:
100 * 300 * 5000 = 150M
possible nodes.
This is far too many. Also the damage should be put as a value and not in the event string. The processing will perhaps be blocked for a game doing this and cause other problems when browsing our tool.
The maximum amount of unique nodes generated should be around 10k.
Business Events
Business events are used to track (and validate) real-money transactions.
Many games are hacked and distributed illegally. Hacking an app will often involve faking/simulating all purchase requests. This will result in several Business events being sent to GameAnalytics for transactions that never occurred.
GameAnalytics provide the option of receipt validation for each purchase sent to GA servers. This process can ensure that revenue metrics reflect the actual spending in your game.
Some configuration is needed before receipt validation will be active.
Read information about validation and requirements for different platforms here.
Android
Android business event with receipt
When submitting a Business Event supply the following from the IAP procedure.
- receipt (INAPP_PURCHASE_DATA)
- signature (INAPP_DATA_SIGNATURE)
Read more about retrieving these needed fields at the Google documentation here.
Add a business event when an in-app purchase is completed (Google Play Store only supported at the moment).
GameAnalytics.addBusinessEvent("USD", 1000, "item", "id", "cart", "[receipt]", "[signature]");
Field | Type | Description | Example |
---|---|---|---|
currency | string | Currency code in ISO 4217 format. | USD |
amount | integer | Amount in cents. | 99 is 0.99$ |
itemType | string | The type / category of the item. | GoldPacks |
itemId | string | Specific item bought. | 1000GoldPack |
cartType | string | The game location of the purchase. Max 10 unique values. | EndOfLevel |
receipt | string | The transaction receipt. Null allowed. | null |
signature | base64 string | The transaction receipt signature. Null allowed. | null |
If the receipt/signature is null (or is an invalid receipt) then it will be submitted to the GA server but will register as not validated.
Android receipt json schema
{
"orderId": "",
"packageName": "",
"productId": "",
"purchaseTime": 1484080095335,
"purchaseState": 0,
"purchaseToken": ""
}
The encoding of the receipt will be done by the GameAnalytics native Android library.
iOS
iOS business event with receipt
When an in-app purchase is completed call the following method.
=GameAnalytics.addBusinessEvent("USD", 999, "Weapon", "SwordOfFire", "Menu", "[receipt]");
Custom Event Fields It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
var fields = new Dictionary();
fields["test"] = 100;
fields["test_2"] = "hello_world";
GameAnalytics.addBusinessEvent("USD", 999, "Weapon", "SwordOfFire", "Menu", "[receipt]", fields);
For more information on custom event fields and raw data export go here.
Field | Type | Description | Example |
---|---|---|---|
currency | string | Currency code in ISO 4217 format. | USD |
amount | integer | Amount in cents. | 99 is 0.99$ |
itemType | string | The type / category of the item. | GoldPacks |
itemId | string | Specific item bought. | 1000GoldPack |
cartType | string | The game location of the purchase. Max 10 unique values. | EndOfLevel |
receipt | base64 string | The transaction receipt. Null allowed. | null |
If the receipt is null (or is an invalid receipt) then the GA servers will register that amount as not validated.
Business event with auto fetch receipt (iOS7+)
Using an alternative method it is possible to let the SDK retrieve the receipt automatically when called directly after a successful in-app purchase. The code performed by the SDK is identical (almost) to the objective-c example above for iOS7+.
Using this method on iOS6.x devices will cause the business event to be ignored. When supporting iOS6 you should retrieve and specify receipt manually.
GameAnalytics.addBusinessEventWithAutoFetchReceipt("USD", 999, "Weapon", "SwordOfFire", "Menu");
Without validation
This is available on all platforms:
GameAnalytics.addBusinessEvent("[currency]", [amount], "[itemType]", "[itemId]", "[cartType]");
For more information on Business Events go here.
Ad Events
Only for Android and iOS!!!
The GameAnalytics ad event needs to be called when certain events happen for the implemented ad sdk’s.
An ad sdk has callback methods activating code when certain things are activated (like ad show or ad clicked).
To use the ad event it is need to call the GameAnalytics SDK when these delegates are called.
The examples below describe how to implement this for the following ad-types.
- rewarded video
- interstitial
- bannner
All code examples use AdMob SDK to showcase example usage. Other ad networks might differ in naming/structure, but the overall process should be applicable to all.
The ad SDK name argument for the ad event needs to be all lower-case with no spaces or underscore used. Here some examples of valid values to use for ad SDK names:
- admob
- unityads
- ironsource
- applovin
Rewarded Videos
Showing a rewarded video
It may pe possible for an ad video to not be available, you can track it using the following method:
if (rewardedVideoAd != null && rewardedVideoAd.isLoaded())
{
// ...show ad
}
else
{
GameAnalytics.addAdEvent(
GAAdAction.FAILED_SHOW,
GAAdType.REWARDED_VIDEO,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
);
}
Tracking video errors
If you want to track errors then we recommend defining this method to map the error message stored earlier in the "latestRewardedVideoError" variable.
function GAAdError getLatestAdError(error)
{
GameAnalytics.GAAdError result = GameAnalytics.GAAdError.Unknown;
// implementation
return result;
}
Tracking rewards
If you want to track rewards from rewarded videos, then call an ad event in the method where rewards are registered. For admob this method is called onRewarded(RewardItem reward) and the following example is a method for how you could handle this.
function onRewarded(reward) {
// send ad event - reward recieved
GameAnalytics.addAdEvent(
GAAdAction.REWARD_RECEIVED,
GAAdType.REWARDED_VIDEO,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
);
}
Tracking completion
You can track the rewarded ad when it has finished being shown.
For admob this method is called onRewardedVideoAdClosed()
and the following example is a method for how you could handle this.
function onRewardedVideoAdClosed() {
if (currentRewardedVideoPlacement != null) {
GameAnalytics.addAdEvent(
GAAdAction.SHOW,
GAAdType.REWARDED_VIDEO,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
);
}
}
If onRewardedVideoCompleted()
is called send the following ad event:
function onRewardedVideoCompleted() {
if(that.get().currentRewardedVideoPlacement != null)
{
GameAnalytics.addAdEvent(
GAAdAction.SHOW,
GAAdType.REWARDED_VIDEO,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
});
}
}
Interstitial
Showing an interstitial ad
if (interstitialAd != null && interstitialAd.isLoaded()) {
interstitialAd.show();
} else {
GameAnalytics.addAdEvent(
GAAdAction.FAILED_SHOW,
GAAdType.INTERSTITIAL,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
);
}
For interstitials you cab track an event at the time it is being shown The following example is a method for how you could handle this.
function onAdOpened() {
// send ad event
GameAnalytics.addAdEvent(
GAAdAction.SHOW,
GAAdType.INTERSTITIAL,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
);
}
Tracking clicks
Call this 0event when onAdLeftApplication()
listener method is called The following example is a method for how you could handle this.
function onAdLeftApplication() {
// send ad event
GameAnalytics.addAdEvent(
GAAdAction.CLICKED,
GAAdType.INTERSTITIAL,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
);
}
Banner ads
Loading a banner ad
If the ad loads successfully send the following ad event when onAdLoaded()
listener method is called. The following example is a method for how you could handle this.
function onAdLoaded() {
GameAnalytics.addAdEvent(
GAAdAction.SHOW,
GAAdType.BANNER,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
);
}
If the ad fails to load we track the latest when onAdFailedToLoad(int errorCode) listener method is called. The following example is a method for how you could handle this.
function onAdFailedToLoad(int errorCode) {
// OR .. if you don't want to track errors
GameAnalytics.addAdEvent(
GAAdAction.FAILED_SHOW,
GAAdType.BANNER,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
);
}
Tracking banner clicks
For admob the banner ad click is registered on the onAdOpened()
listener method. Call an ad event at this time for banner ads. The following example is a method for how you could handle this.
function onAdOpened() {
// send ad event
GameAnalytics.addAdEvent(
GAAdAction.CLICKED,
GAAdType.BANNER,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]"
);
}
Custom Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
var fields = new Dictionary();
fields["test"] = 100;
fields["test_2"] = "hello_world";
GameAnalytics.addAdEvent(
GAAdAction.CLICKED,
GAAdType.BANNER,
"admob",
"[AD_PLACEMENT_OR_UNIT_ID]",
fields
);
For more information on custom event fields and raw data export go here.
Field | Type | Description | Example |
---|---|---|---|
adAction | enum | A defined enum for ad action (for example clicked). | GAAdAction.Clicked GAAdAction.Show GAAdAction.FailedShow GAAdAction.RewardReceived |
adType | enum | A defined enum for ad type (for example interstitial). | GAAdType.Video GAAdType.RewardedVideo GAAdType.Playable GAAdType.Interstitial GAAdType.OfferWall GAAdType.Banner |
adSdkName | string | Name of the Ad/Ad mediation SDK. | admob |
adPlacement | string | Identifier of ad in the game or the placement of it. | level_complete_ad |
adPlacement | string | Identifier of ad in the game or the placement of it. | level_complete_ad |
duration | int | Optional. Only used for video ads to track how long the user watched the video for. | 10 |
noAdReason | enum | Optional. Used to track the reason for not being able to show an ad when needed (for example no fill). | GAAdError.Unknown GAAdError.Offline GAAdError.NoFill GAAdError.InternalError GAAdError.InvalidRequest GAAdError.UnableToPrecache |
For more information on Ad Events go here.
Resource Events
Resource events are used to register the flow of your in-game economy (virtual currencies) – the sink (subtract) and the source (add) for each virtual currency.
Before calling the resource event it is needed to specify what discrete values can be used for currencies and item types in the Configuration phase.
source (add) Gem currency from an in-app purchase
GameAnalytics.addResourceEvent(GAResourceFlowType.SOURCE, "Gems", 400, "IAP", "Coins400");
sink (subtract) Gem currency to buy an item
GameAnalytics.addResourceEvent(GAResourceFlowType.SINK, "Gems", 400, "Weapons", "SwordOfFire");
sink (subtract) Gem currency to source (buy) some amount of another virtual currency (BeamBooster)
GameAnalytics.addResourceEvent(GAResourceFlowType.SINK, "Gems", 100, "Boosters", "BeamBooster5Pack");
GameAnalytics.addResourceEvent(GAResourceFlowType.SOURCE, "BeamBooster", 5, "Gems", "BeamBooster5Pack");
sink (subtract) 3 BeamBooster currency that were used during a level
GameAnalytics.addResourceEvent(GAResourceFlowType.SINK, "BeamBooster", 3, "Gameplay", "BeamBooster5Pack");
Custom Resource Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
var fields = new Dictionary();
fields["test"] = 100;
fields["test_2"] = "hello_world";
GameAnalytics.addResourceEvent(
GAResourceFlowType.SINK,
"BeamBooster",
3,
"Gameplay",
"BeamBooster5Pack",
fields
);
For more information on custom event fields and raw data export go here.
Field | Type | Description | Example |
---|---|---|---|
flowType | enum | A defined enum for sourcing and sinking resources. | GAResourceFlowType.SOURCE |
currency | string | The resource type/currency to track. Has to be one of the configured available resource currencies. This string can only contain [A-Za-z] characters. | Gems, BeamBoosters, Coins |
amount | float | Amount sourced or sinked. 0 or negative numbers are not allowed. | 100.0 |
itemType | string | For sink events it can describe an item category you are buying (Weapons) or a place (Gameplay) the currency was consumed. For source events it can describe how the currency was gained. For example “IAP” (for in-app purchase) or from using another currency (Gems). Has to be one of the configured available itemTypes. | Weapons, IAP, Gameplay, Boosters |
itemId | string | For sink events it can describe the specific item (SwordOfFire) gained. If consumed during Gameplay you can simply use “Consumed”. For source events it describes how the player got the added currency. This could be buying a pack (BoosterPack5) or earned through Gameplay when completing a level (LevelEnd). | BoosterPack5, SwordOfFire, LevelEnd, Coins400 |
Be carefull to not call the resource event too often !
In a game where the user collect coins fairly fast you should not call a Source event on each pickup. Instead you should count the coins and send a single Source event when the user either complete or fail the level.
For more information on Resource Events go here.
Progression Events
Progression events are used to track attempts at completing some part of a game (level, area). A defined area follow a 3 tier hierarchy structure (could be world:stage:level) to indicate what part of the game the player is trying to complete.
When a player is starting a progression attempt a start event should be added. When the player then finishes the attempt a fail or complete event should be added along with a score if needed.
Add a progression start event.
GameAnalytics.addProgressionEvent(GAProgressionStatus.START, "world01");
GameAnalytics.addProgressionEvent(GAProgressionStatus.START, "world01", "stage01");
GameAnalytics.addProgressionEvent(GAProgressionStatus.START, "world01", "stage01", "level01");
Add a progression complete event.
GameAnalytics.addProgressionEvent(GAProgressionStatus.COMPLETE, "world01", 1000);
GameAnalytics.addProgressionEvent(GAProgressionStatus.COMPLETE, "world01", "stage01", 1000);
GameAnalytics.addProgressionEvent(GAProgressionStatus.COMPLETE, "world01", "stage01", "level01", 1000);
It is not required to use all 3 if your game does not have them.
- progression01
- progression01 and progression02
- progression01 and progression02 and progression03
Custom Progression Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
var fields = new Dictionary();
fields["test"] = 100;
fields["test_2"] = "hello_world";
GameAnalytics.addProgressionEvent(GAProgressionStatus.COMPLETE, "world01", "stage01", "level01", 1000, fields);
For more information on custom event fields and raw data export go here.
Field | Type | Description | Example |
---|---|---|---|
progressionStatus | enum | Status of added progression | GAProgressionStatus.START GAProgressionStatus.FAIL GAProgressionStatus.COMPLETE |
progression01 | string | Required progression location. | World01 |
progression02 | string | Not required. Use if needed. | Stage01 |
progression03 | string | Not required. Use if needed. | Level01 |
score | integer | An optional score when a user completes or fails a progression attempt | 1023 |
For more information on Progression Events go here.
Error Events
Used to track custom error events in the game. You can group the events by severity level and attach a message.
To add a custom error event call the following function:
GameAnalytics.addErrorEvent(GAErrorSeverity.DEBUG, "Something went bad in some of the smelly code!");
Custom Error Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
var fields = new Dictionary();
fields["test"] = 100;
fields["test_2"] = "hello_world";
GameAnalytics.addErrorEvent(GAErrorSeverity.DEBUG, "Something went bad in some of the smelly code!", fields);
For more information on custom event fields and raw data export go here.
Field | Type | Description | Example |
---|---|---|---|
severity | enum | Severity of error | GAErrorSeverity.DEBUG GAErrorSeverity.INFO GAErrorSeverity.WARNING GAErrorSeverity.ERROR GAErrorSeverity.CRITICAL |
message | string | Error message (can be null) | “Error when entering level12” |
For more information on Error Events go here.
Design Event
Every game is special. Therefore some needed events might not be covered by our other event types. The design event is available for you to add your own event-id hierarchy.
Please note that custom dimensions and progression filters will not be added on design and error events. Therefore you cannot (at the moment) filter by these when viewing design or error metrics.
To add a design event call the following method.
GameAnalytics.addDesignEvent("Kill:Sword:Robot");
It is also possible to add a float value to the event. This will (in addition to count) make the mean and sum aggregation available in the tool.
GameAnalytics.addDesignEvent("BossFights:FireLord:KillTimeUsed", 234);
Custom Design Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
var fields = new Dictionary();
fields["test"] = 100;
fields["test_2"] = "hello_world";
GameAnalytics.addDesignEvent("BossFights:FireLord:KillTimeUsed", 234, fields);
For more information on custom event fields and raw data export go here.
Field | Type | Description | Example |
---|---|---|---|
eventId | string | The eventId is a hierarchy string that can consist of 1-5 segments separated by ‘:’. Each segment can have a max length of 32. | “StartGame:ClassLevel1_5”, “StartGame:ClassLevel6_10” |
value | float | A float event tied to the eventId. Will result in sum & mean values being available. | 34.5 |