Introduction

The deltaDNA SDK for Unity allows your to send information on player actions from your game to deltaDNA for analysis, reporting, CRM and gameplay personalisation.

Events are cached on the client to prevent loss whilst playing offline and sent to the deltaDNA platform at regular intervals as JSON objects. Events vary in complexity but are all derived from a common event schema. This document and the accompanying demo application provide examples of increasingly complex events.

The source code for the SDK, written in C#, is provided as a packaged Unity asset and has no external dependencies. Games successfully send data to deltaDNA using the Unity SDK from a wide range of Unity target platforms including Xbox, Playstation, PC, Web GL, iOS, Android etc.  It should be noted that deltaDNA is not currently a certified Xbox or Sony technology partner so there may be some support scenarios where we will be unable to replicate or debug individual customer implementations.

This page will cover the following aspects of the deltaDNA Unity SDK:

Important changes: previous versions of the SDK and release notes are available on the Releases Notes page and from version 4 onwards in the changelog on our GitHub page

Initializing the SDK

The SDK should be imported into your Unity project as a package configured with the following details.

SDK Configuration

  • Environment Key (Dev) – A unique 32 character string to route data to your DEV environment.
  • Environment Key (Live) – A unique 32 character string to route data to your LIVE environment.
  • Selected Key – Choose DEV or LIVE from the drop-down list to ensure data is routed to the correct environment for your game. Use the DEV environment for testing and QA then remember to switch to live before submitting a production build to the store.
  • Collect URL – the address of the server that will be collecting your events.
  • EngageURL – the address of the server that will provide real-time A/B Testing and Targeting. This is only required if your game uses these features.

These configuration details can be found on your game details page. Please note that there are different environmentKey values for your DEV & LIVE environments. You will need to change the environment key that you initialize the SDK with as you move from development and testing to production.

Enter these parameters into the configuration panel accessed from the deltaDNA -> Configure menu inside the Unity Editor and Apply your changes.

Now you can add a script to a new or existing game object to start the deltaDNA SDK.
For any SDK versions < 6.0.0, this is the minimum amount of code required to initialize the Unity SDK and start sending events:

For SDK versions 6.0.0 and above, you will need to check if the user would be affected by the China Personal Information Protection Law before starting the SDK. Here is the required code to initialize the SDK and start sending events:

Note: In the above code sample, the variable hasDataUseConsent should only be set to true if you have received permission from the user to collect data for analytics purposes from them, and the variable hasDataExportConsent should only be set to true if you have received permission from the user to export the data collected about them outside of China.
The SDK will automatically send the newPlayer event the first time it is run and the gameStarted and clientDevice event each time the game runs.

By default, the deltaDNA SDK will generate its own anonymous userID, but you can choose to use your own identity, one provided by another game services or login provider, just put it in the StartSDK method e.g. DDNA.Instance.StartSDK("ABCD-1234-GG-5678-ETC...");

The userID will be persisted on the client and used in all subsequent events for the duration of the games install unless you change it yourself (not advised!).

Anatomy of an Event

All events are recorded as JSON documents with a shared basic schema. The document will be different for every event type but all of them should adhere to the following minimal schema:

The Unity SDK will automatically populate the userID, sessionID, eventTimestamp, eventUUID,  platform & sdkVersion parameters for every event you send. When you add parameters to an event they will all be placed inside the eventParams object.

The order of the parameters in your JSON event doesn’t matter, but take care as they are case sensitive and need to match the type defined in the Event Manager

You can inspect the parameters that each event expects, their type and any formatting or enumeration rules in the Event Manager.

Parameters can be either Optional or Required. Any parameters that are are optional don’t have to be included in your event if you don’t have a valid value to put in them. It is better to leave them out completely, than set their value to null or empty.

This basic event structure provides great flexibility for recording events with varying levels of complexity, from simple events like the one above to complex events containing nested arrays. The following code examples will show a variety of events from simple to complex.

Please note that all events are validated and will be rejected if they don’t match the schema in the Event Manager 

Settings

The simple initialization code, copied from your game details page and shown above, is the minimum code required to start collecting analytics data from your players. You will quickly want to start adding more events and fine-tuning your implementation. Here’s the same initialization code with a couple of useful settings added.


These two additional settings will:

  1. Tell the SDK to output detailed debug on the events you are collecting and communications with deltaDNA. This is particularly useful when used in conjunction with the QA – Interactive Validator during development, as it will help you resolve any issues that are causing any of your events to fail validation.
  2. Set the clientVersion of your game. This is advisable and can very useful for identifying behavioural differences between players on different builds of your game. Especially when a client version update is option that many mobile users don’t bother with. You may even have spotted a warning about the client version not being set when you ran the simple initialization code, setting the ClientVersion will resolve it.N.B. The Unity SDK can also pull the build version from your Player Settings page and use it to populate the clientVersion automatically for you. Set the checkbox on the DeltaDNA Configuration page in the Unity Editor to enable this feature.
There are many other useful settings that will help you with push notification messages, device IDs, event hashing, automated event collection and automated communications, be sure to check them out in the example app that ships with the SDK or the built-in Tool Tips.

Example 1 – A Simple Event

The initialization code that we have seen already will send the newPlayer, clientDevice, gameStarted and gameRunning events to deltaDNA automatically. In the following code we will add an event ourselves in code.

When we added our game to deltaDNA some default events were automatically added, these events tend to be standard across all games and are used to drive many of the dashboards. For now we will just use one of those standard events, the options event. Other standard events can be seen by visiting Setup > View Events and any of these events can be sent to us so long as the schema in your game matches the schema on the platform.

The following JSON event would be uploaded

Example 2 – Adding a New Template Event

The previous example used one of our standard events, this time we will do something a bit more ambitious, we will add a custom parameter to an event, then trigger the event from our code.

Navigate to the SETUP > Manage Events page in your DEV environment and look for the missionStarted event, if you don’t see it you may need to add it by clicking the Create Event button and adding it from the drop-down list of event templates.

Click the Edit button on the missionStarted event, select the eventParams object then add a new missionDifficulty parameter of type STRING.

The code to trigger the missonStarted event:

The following JSON event would be uploaded:

Pasting event JSON into the Interactive Event Validator can help resolve errors, our missionStarted event passed validation first time.

Example 3 – A Complex Event

The previous examples have been pretty straightforward and haven’t required much explanation. However, the following one is a bit more complex as it introduces nesting, arrays and some special objects that you will encounter when the player buys, trades, wins, exchanges currency.  The good news is, the structure for this is fairly standard, there are some helper methods and this is as complex as it gets.

We are going to trigger a transaction event that records the player using some real-world currency to purchase a treasure chest containing some virtual currency and multiple items. We will also take advantage of deltaDNA revenue validation with the Apple store to check that the transaction is valid.

As you can see the structure of the transaction event is a bit more complex. It contains a couple of Product objects for recording productsSpent and productsReceived.

Our JSON event will end up looking like

and the following code was is required to create it using the Transaction helper class.

Or you can use a GameEvent helper.

 

Please note: You can’t simply multiply the decimal value of a currency by 100 to get the value in the smallest currency unit, some currencies don’t have 2 currency units after the decimal point.

There is a method in the SDK that can help you with this. The Product class contains a  ConvertCurrency(string code, decimal value) method that returns an integer representation which can be used with the SetRealCurrency method.  This method will also work for currencies which don’t use a minor currency unit, for example such as the Japanese Yen (JPY).

Alternatively, check the ISO-4217,  3 character currency code documentation and confirm the multiplication factor that you should apply to each realCurrencyType.

The above snippet is $4.99 USD

This event may be more complex but the structure is logical, flexible and provides a mechanism for players spending or receiving any combination of currencies and items.

The three terms listed below are our best practice guidelines for the three general types of virtual currency, defined by their source.

GRIND = currency that is earned through gameplay or game features.
PREMIUM = currency that can either be purchased through purchases with real-world currency.
PREMIUM_GRIND = currency that can come from either of the above sources.

The currencyType doesn’t have an effect on the revenue dashboards – they are just there to distinguish transactions when performing further analysis on the data. You can send these default types or another enumeration can be added if there is something more appropriate for your game.

Transaction Validation

The platform can undertake transaction receipt validation with various Stores in order to ensure that any revenue displayed in your dashboards is genuine revenue and not the result of a hacked or Jail broken game.

If you wish to use transaction validation you will need to add a couple of details to the “Edit Game Details” page that can be reached from the “Manage Games” link on the left of the Welcome Screen.
e.g. for Apple you would set your 9 digit Apple StoreID. 971883677 and the URL to the Apple Receipt Validation service https://buy.itunes.apple.com/verifyReceipt in order to validate against the Production receipt validation service.
N.B. – If you are sending test receipts, set your StoreID to 0  and set the validation URL to https://sandbox.itunes.apple.com/verifyReceipt

You also need to send additional parameters along with each transaction event to tell deltaDNA that the transaction should be validated.

e.g. To validate an Apple store IAP

The transactionReceipt is the BASE 64 encoded receipt data that was returned from Apple. Please refer to the Apple developer website for details on Apple Receipt Validation

To validate Google Play IAP send the transactionServer, the purchase data as the transactionReceipt and the ‘in app data signature’ as transactionReceiptSignature

N.b. since the transactionReceiptSignature is generated from the transaction receipt and a private key in order to validate the receipt this will need to be exactly the string as provided by Google and passed as a string, not a nested JSON object.

deltaDNA will then validate your revenue and add an additional revenueValidated parameter, containing the following potential values, to your transaction event.

  • 0 – no validation performed
  • 1 – revenue passed validation check
  • 2 – revenue failed validation check
  • 3 – revenue validation attempted, but result unknown (validation service may have been unavailable)

Transactions that fail validation with status code 2 or 3 will be excluded from your Measure Revenue charts and user metrics.

Since sandbox transactions do not actually generate revenue these are not shown by default in the revenue charts but if you would like to have these show up you can choose the sandbox URL on the”Edit Game Details” page (https://sandbox.itunes.apple.com/verifyReceipt), use 0 as the Apple StoreID and omit sending the transactionID since this is not part of the sandbox receipt. We strongly advise you do a final test with an actual transaction against the Apple Store since only such a transaction has all fields correctly set up.

There is a webinar and accompanying powerpoint presentation covering revenue validation in more detail on the Webinars page.

Example 4 – Engage Decision Point Campaigns

Games can retrieve time-sensitive information from Engage to modify or personalise the game for individual players at run-time, based on the results of an in-game Campaign or A/B Test defined in the deltaDNA UI. Your game can make Engage requests at predetermined decision points in your game and the response will allow you to personalise the gameplay or override the default settings for that user instantly.

The following example shows how you can use an Engage Decision Point Campaign to change an IAP offer made to the player :

  1. Create a Decision Point campaign on the deltaDNA platform
  2. Make an Engage request in your code
  3. And react to the response in a callback.

For code snippets regarding Engage calls see our GitHub documentation page.

For all engage calls a JSON response will be returned to you. Your game should be structured in such a way that is won’t stall if the user is on a high latency connection.

The engage response contains a transactionID and a parameters object containing any parameters relevant to this player at this point in time.

If the device doesn’t have internet connectivity at the time of the Engage request a cached response from the last successful Engage request for the same decision point will be contained in the response. The isCachedResponse parameter will indicate that this is a cached response.

You may receive a response containing a transactionID but no parameters. This indicates that the player has failed to meet any qualification criteria or has been allocated to a control group.

If there was an error processing your Engage request at the server your response will contain a statusCode parameter containing the relevant status code.

  • 400 – inputs malformed or incorrect in some way, or you are sending real-time parameters that haven’t been added to your Game Parameter list.
  • 403 – secret hash key incorrect or Engage is not enabled on your account.
    Please check that you have the “On-Demand” package enabled on your Game -> Packages page, you may need to get the Account Owner for your deltaDNA account to do this for you.
  • 404 – incorrect URL or unknown environmentKey

Image Messaging

Engage Campaigns can deliver popup messages to your game at run-time. Re-usable Image Messages are created in the Action Manager (Engage->Actions) and assigned in the Campaign Manager (Engage->Campaigns). The Unity SDK has a Popup class that draws the image message over your game. The popup is event driven so you are able to control when the image is downloaded from our servers, and when it is presented to the player.

Each message consists of two parts, a sprite map contains images for the background and a number of buttons, and a layout describing how to display these parts. The layout uses constraints to workout how to scale and where to place the popup. This means we don’t have to worry about screen sizes, but we can also protect parts of the screen from being covered up. The image is drawn as large as possible within those constraints whilst still maintaining the original aspect
ratio.

An Image Messaging Engage Request is the same as any other Engage campaign request.

The response message contains the image and layout information for the popup as well as information on any actions assigned to the images.

  • The url is the location of the sprite map image file. The width and height are the size of the image, and the format is the image format.
  • The spritemap object describes the location of the image assets in the sprite map. The buttons are optional depending on the number of buttons in the message.
  • The layout object describes how the background is to appear on the screen. It contains landscape and/or portrait keys depending on preferred layout. If only one key is present the rules are applied whatever the orientation.The layout orientation contains rules for the background and the location of the buttons. For the background two modes are valid:
    cover which scales the background image so it’s as large as possible, and
    contain which makes the image as large as possible such that all the constraints are satisfied.
  • Each background and button object can have an action. The action type can be none, dismiss, link or action.
    If the type is link or action a value field will provide a string value to pass back to the callback associated with the button. If a link, then the browser is opened automatically by the SDK.

  • The shim field describes how the remainder of the screen behind the message should be handled. The mask can be either
    none, in which case nothing is added so any buttons behind the popup can still be clicked,
    clear which will have the effect of preventing background buttons from being clicked, and
    dimmed which greys out the screen.The shim also supports actions so clicking on it can dismiss the popup too.

See our GitHub page on how to implement the image engagement and handle the optional parameters returned along with the image.

Android Push Notifications

The deltaDNA SDK can request an Android registration ID for a player’s device and communicate it to the deltaDNA platform using a notificationServices event – although you may need to add this event to your game in the Event Manager. This ID can be used by deltaDNA to send targeted push notification messages to the device.

The Firebase Cloud Messaging service is used by deltaDNA to send push notifications as part of an out of game campaign.

Before the SDK can be used to register the device for push notifications there are a couple of steps you must first complete. These are:

  • Retrieve the sender ID and application ID from Firebase. More information about retrieving these values and setting up FCM can be found in our FCM Setup guide)
  • Configure these values in your project in the configuration screen – this can be accessed from the Unity Editor menu under DeltaDNA > Notifications > Android Configure

The following line of code can then be used to register the device for push notifications:

This will retrieve the Android registration ID from the device and send it to the deltaDNA platform to be used as a target for push notifications. In order for the platform to use this device ID as a target you must configure your Google API key in the platform – the process for this can be seen in the FCM Guide under Retrieving Configuration Values.

More information on Android push notifications and Unity SDK integration in general can be found in our Unity SDK GitHub page.

It is recommended that you make use of Firebase Cloud Messaging however some older applications may still use Google Cloud Messaging – information about retrieving configuration values from GCM can be found in our GCM Setup guide

Apple (iOS) Push Notifications

The deltaDNA SDK for Unity can store the Apple Push Notification Token and send it to deltaDNA allowing the deltaDNA platform to send targeted push notification messages to players.  Your application will be responsible for requesting a push notification from Apple.

To request a push notification token from Apple:

The token will be sent to deltaDNA in a notificationServices event. You may need to add the notificationServices event to your game using the Event Manager.

You will also need to upload your iOS Certificate to the deltaDNA platform in order for Apple to accept push notification requests from deltaDNA, you can do this in the SETUP -> TOOLS – NOTIFICATIONS -> Manage Identity Page. Your certificate from Apple needs to contain both your certificate and key and be saved as a .p12 file.CertificateIcon

Check out our Apple Certificate Guide, for more information on how to provision your App to receive Push Notification Messages, create a certificate and save the it in the correct format.

Apple Identifiers

Apple Advertising Identifier and VendorID deltaDNA does not record the advertising identifier or vendorID.

If you wish to record these parameters in deltaDNA you are responsible for retrieving them from the device and sending them as custom parameters with any events you wish to attach them to. You will also need to add these custom parameters in the event management tool.

Event Timestamps

The Unity SDK automatically timestamps events using the clock on the client device. This can cause inaccuracies when the device is not set to the correct time or date and even cause events to get rejected if the time is too far out. However, the local timestamping behaviour can be overridden and you can provide your own timestamping method that will be used to timestamp events.

It is also possible to completely disable timestamping on the device and send events without a timestamp, this will result in the event being timestamped with the Collect server time when the event is received. We don’t recommend this approach though as there are a couple of undesirable side effects.

  • The Unity SDK caches player events locally to ensure they are not lost if the devices loses connectivity. It is therefore possible for events to be received many days after they occurred.
  • Events are uploaded in batches containing multiple events as this is much more efficient than sending them one at a time. If you were to use Collect server timestamping this would make it look like the player is playing in frantic bursts. Events would look like they all happened within a few milliseconds of each other and then nothing until the next batch is uploaded.

If you must use Collect server timestamping you can do so by setting  DDNA.Instance.UseCollectTimestamp(true);

Unity Audience Pinpointer

If you are using Unity Audience Pinpointer please follow the additional steps described in the Unity Audience Pinpointer Integration Guide