Amazon Services for Data Sync, Player Engagement & A/B Testing (MBL309) | AWS re:Invent 2013

Preview:

DESCRIPTION

Is your mobile app or game built to run on multiple platforms? Do you want a fast, straightforward solution to common problems like data synchronization, player achievements, and leaderboards? Amazon offers several services that allow you to plug-and-play features in your mobile app or game, with very little set-up and no server-side development. This session provides instructions for integrating GameCircle (Whispersync for Games, Achievements, Leaderboards) in your Android apps, and demonstrates how to add A/B Testing and fine tune your app based on user response. Learn how to speed up your time to market, regardless of whether you distribute through Google Play or the Amazon Appstore.

Citation preview

© 2013 Amazon.com, Inc. and its affiliates. All rights reserved. May not be copied, modified, or distributed in whole or in part without the express consent of Amazon.com, Inc.

MBL309 Speeding Mobile Development with Cross-Platform APIs: High-Level Amazon Services for Data Sync, Player Engagement, and A/B Testing

Sourabh Ahuja, Glu Mobile Peter Heinrich, Amazon Appstore

November 13, 2013

What Can We Do for You?

Whispersync for Games Leaderboards Achievements

A/B/n Testing Engagement Reports

Analytics Launches

© 2013 Amazon.com, Inc. and its affiliates. All rights reserved. May not be copied, modified, or distributed in whole or in part without the express consent of Amazon.com, Inc.

Glu and Amazon: Whispersync for Games

Whispersync: Downloading from Cloud

• How: – 1.x:

• multi-file synchronize API call and setup conflict strategy – 2.0:

• via Whispersync callbacks & GameDataMap Handle • What:

– 1.x: • developer string + all files residing in the internal memory for that game

– 2.0: • Developer string + syncablestring (i.e. raw game data)

• When: – game launch - AmazonGamesClient.getWhispersyncClient().synchronize();

Whispersync: Uploading to Cloud

• What: – developer string and raw game data byte[] (using SyncableString).

• When: – game calls save. – force save (flush) before closing the game [WhispersyncClient->flush()]

Whispersync: Uploading to Cloud Code Sample

public static void sync( String developerStringLocal, byte[] rawGameData ) { developerStringCloud.setValue(developerStringLocal); rawDataLocal = rawGameData; } private static void onDataUploadedToCloud() { // Once cloud data is available on the device, Whispersync can check for conflicts if (developerStringCloud.inConflict()) { //display the values to the user. if(useCloudData) { developerStringCloud.setValue(developerString.getCloudValue()); OverwriteLocalSaveData(rawDataCloud); developerStringCloud.markAsResolved(); Restart(); } developerStringCloud.markAsResolved(); } rawDataCloud.set(Base64.encodeToString(rawDataLocal, Base64.DEFAULT)); whisperSyncClient.synchronize(); }

Whispersync: Developer String

• Pick data which is core to the game – Should make sense to the user.

• Data that changes in one direction – Player Level, Missions/Levels Unlocked, etc.

• Data to avoid – Data the changes in both direction — e.g., currencies, energy,

etc.

Whispersync: Developer String Starting at Level 2

Whispersync: Developer String Conflict Detected

Whispersync: Developer String User Chooses Cloud Data

Whispersync: Developer String Game Restored Using Cloud Data

Whispersync: Developer String

• Ideal for games that haven't modeled the save data according to GameCircle 2.x’s Syncable Data Types

• Easy to implement • User gets to make the choice • Auto-resolving is risky • Works offline

Whispersync & Unity: Tips and Tricks

Page 13 © Glu Mobile Inc Private

Whispersync & Unity - Tips & Tricks

• Avoiding game restart on first launch – Loading cloud data is asynchronous:

• Halt the game progress before game state is loaded from disk • If Whispersync callback successfully retrieves data from cloud and

it is the first launch, then load game state using cloud data

1.x 2.x - Tips & Tricks

• In the Whispersync onNewCloudData callback: – Retrieve developer string from gameDataMap. If the string is

null, only then do the migrations mentioned below: • Single file steps:

– API call to retrieve 1.x data – Load game from the cloud data

• Multi-file steps: – API call to retrieve 1.x files – API call to copy 1.x files to specific location

© 2013 Amazon.com, Inc. and its affiliates. All rights reserved. May not be copied, modified, or distributed in whole or in part without the express consent of Amazon.com, Inc.

Player Engagement with GameCircle Leaderboards & Achievements

Engagement is Important

56%

of purchases are repeat purchases

62%

of revenue occurs after the first 7 days

35%

of revenue occurs after the first 30 days

Source: Amazon Appstore, July 2013

Display Prominently

Encourage Friendly Competition

Reward Completion

Engagement Service? Get a Head Start: • Leaderboards • Achievements • Game Center

integration on iOS • Android, Fire OS

GameCircle: Auth(oriz|entic)ation

Security Profiles + API Keys

Enable Access on Server

Create a security profile

Associate it with GameCircle data

Associate each permitted app

Enable Access on Client

Compute MD5 of certificate store

Generate an API key

Add key to app

heinrich@DevMachine7 ~/.android $ cd ~/MonsterTag heinrich@DevMachine7 ~/MonsterTag $ unzip -p bin/MonsterTag.apk META-INF/CERT.RSA | keytool -printcert | grep MD5 MD5: D4:85:0C:AE:3D:45:DF:45:59:F2:BE:DE:95:A8:E1:62

heinrich@DevMachine7 ~ $ cd ~/.android heinrich@DevMachine7 ~/.android $ keytool -list -v -alias androiddebugkey -keystore ./debug.keystore | grep MD5 Enter keystore password: android MD5: D4:85:0C:AE:3D:45:DF:45:59:F2:BE:DE:95:A8:E1:62

Compute MD5 Signature

GameCircle: Leaderboards

Submit a Score AmazonGamesClient agsClient; public void submitScore(long score) { LeaderboardsClient lbClient = agsClient.getLeaderboardsClient(); AGResponseHandle<SubmitScoreResponse> handle = lbClient.submitScore(TAGGED_LB, score); // Optional callback to receive notification of success/failure. handle.setCallback(new AGResponseCallback<SubmitScoreResponse>() { @Override public void onComplete(SubmitScoreResponse result) { if (result.isError()) { // Retries are automatic, so no action strictly required } else { // Special handling of your own. } } }); }

Other APIs • Retrieve player’s current score or rank • Retrieve filtered list of top scores • Get a list of leaderboards • Show the Leaderboard overlay

GameCircle: Achievements

Updating Progress AmazonGamesClient agsClient; public void unlockAchievement(View view) { AchievementsClient acClient = agsClient.getAchievementsClient(); AGResponseHandle<UpdateProgressResponse> handle = acClient.updateProgress(KING_AC, 100.0f); // Optional callback to receive notification of success/failure. handle.setCallback(new AGResponseCallback<UpdateProgressResponse>() { @Override public void onComplete(UpdateProgressResponse result) { if (result.isError()) { // Retries are automatic, so no action strictly required } else { // Special handling of your own. } } }); }

Other APIs • Retrieve info for a single achievement • Get a list of all achievements • Show the Achievement overlay

© 2013 Amazon.com, Inc. and its affiliates. All rights reserved. May not be copied, modified, or distributed in whole or in part without the express consent of Amazon.com, Inc.

Using A/B Testing to Modify Live Apps without Republishing

Air Patriots Used A/B Testing to decide: • Include in-game advertising? • Provide purchasing short-cuts? • Notification frequency? • Reduce difficulty? • Promotional imagery?

Air Patriots

Air Patriots

Launch Service

Precisely control who is affected

Change in the wild; No new APK needed

Safely test back-end load

private static final String APP_KEY = "876c809ba7084b9fbe2c08a22e5acda1"; private static final String PRIVATE_KEY = "9nxxk4//qL89ymXl/P5aL7w8uhs3DVDrLcyYViG6yn0="; AmazonInsights insightsInstance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); . . . InsightsCredentials credentials = AmazonInsights.newCredentials(APP_KEY, PRIVATE_KEY); insightsInstance = AmazonInsights.newInstance(credentials, getApplicationContext()); }

Initialize A/B Testing in Your App

Multiple Projects Are Allowed

private static final String AB_MAXACC = "Acceleration"; private static final String AB_MAXACC_VAR = "maxAcceleration"; private static final String AB_MAXVEL = "Velocity"; private static final String AB_MAXVEL_VAR = "maxVelocity";

Load Variation Variables private static final int DEF_MAXACC = 5;

private static final int DEF_MAXVEL = 50;

private int maxAcc;

private int maxVel; private void loadTreatment() { ABTestClient abClient = insightsInstance.getABTestClient(); abClient.getVariations(AB_PRJ_VEL, AB_PRJ_ACC).setCallback(new InsightsCallback<VariationSet>() { @Override public void onComplete(VariationSet variations) { Variation variation = variations.getVariation(AB_PRJ_ACC); maxAcc = variation.getVariableAsInt(AB_VAR_MAXACC, DEF_MAXACC); variation = variations.getVariation(AB_PRJ_VEL); maxVel = variation.getVariableAsInt(AB_VAR_MAXVEL, DEF_MAXVEL); } }); }

Let Us Do That for You • Amazon GameCircle

– Data Synchronization with Whispersync for Games – Player Engagement with Leaderboards and Achievements

• A/B Testing – Real-time Control Knobs for Live Apps with Launches

Please give us your feedback on this presentation

As a thank you, we will select prize winners daily for completed surveys!

MBL309