(SOV203) Understanding AWS Storage Options | AWS re:Invent 2014
Amazon Services for Data Sync, Player Engagement & A/B Testing (MBL309) | AWS re:Invent 2013
-
Upload
amazon-web-services -
Category
Technology
-
view
1.353 -
download
1
description
Transcript of Amazon Services for Data Sync, Player Engagement & A/B Testing (MBL309) | AWS re:Invent 2013
© 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