Android Cloud Saving on Android

Discussion in 'Tutorials' started by Appsurd, May 30, 2017.

  1. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Google Play services cloud saving on Android


    GM version: GM: Studio 1.4.1804 Professional (2018-03-18)
    Target platform: Android
    Download: https://marketplace.yoyogames.com/assets/5485/cloud-saving-example
    Links: https://marketplace.yoyogames.com/assets/2008/google-play-services
    Latest change: 2018-08-10
    Level: Advanced



    Summary

    In this tutorial we will be exploring the setup of cloud saving on Android devices. You can save any information in your game to the server, and keep the variables updated whenever needed. The complete implementation is actually rather simple, since I made all scripts for you and you only need to add them to your game. Don’t forget to add the Play Services API from YoyoGames: https://marketplace.yoyogames.com/assets/2008/google-play-services

    Table of contents

    Introduction
    Chapter 1: Setting up the Google Play Console part 1
    Chapter 2: Setting up GameMaker: Studio
    Chapter 3: Setting up the Google Play Console part 2
    Chapter 4: Cloud saving in practice
    Conclusion
    Error solving: Common issues
    Changelog

    Introduction

    Hey there and welcome to another tutorial from Appsurd. Today I will discuss the topic of cloud saving on Android devices. This feature is really useful when you have a big app and you want to have the player keep his progress after he/she swapped device. Simply inviting users to use the Google Play Games on the device ensures that this method is possible!

    We will first be covering the setup in the Google Play Store. For testing out this tutorial you need to have your own Google Play Dev account, so if you don’t have one, you can’t test it I’m afraid. After that, we will head for GameMaker: Studio to put in some code and finally, we will finish the job in the Google Play Console. I made a small example which can be downloaded in the Marketplace: https://marketplace.yoyogames.com/assets/5485/cloud-saving-example. In the last chapter, I will be discussing some real-life implementations of how one could use this system in a handy way in your own app.

    This tutorial and all its assets are completely free, there is no need for any credit at all to Appsurd. We do appreciate if you rate the script in the Marketplace such that we know what can be improved. Thanks in advance and enjoy the tutorial!

    Chapter 1: Setting up the Google Play Console part 1

    Since we want to make use of Google’s build-in functionality, we need to enable this for our app. Unfortunately, we cannot test this functionality without actually making a whole project, so we will be going through this process quickly. Naturally we will be skipping parts like adding screens and other game info, but for your final app you definitely want to fill that in. Now let’s start.

    Just go to your Google Play Console and login. Then choose in the left column for “Game services”. Now we wish to create a new app. See Figure 1.

    [​IMG]
    Figure 1: The Google Play Console. Select the “Game services” in the left column. Then press “Add new game” as indicated by the orange frame.​


    Now a screen pops up asking you for the name of the game. I will call him “Tutorial Cloud Saving” but you might as well be giving it the name of your game! Then choose a category of your game, it doesn’t really matter for the tutorial, but again, in case you are planning to use this project for your real app, just choose the correct category. Then press “Continue”, see Figure 2 for more details.

    [​IMG]
    Figure 2: The setup for the Play Services. Fill in the name of your game and below that, choose its category. Then press “Continue”.​


    After pressing “Continue”, you might need to wait for a couple of seconds or maybe a minute, since Google is setting up the game services. We now wish to go to “Linked apps”. Select it from the menu on the left. In the middle at the top of the page, just below the title of your project, you will see a number. This is your App ID and you need to save this number somewhere, as we will need it to link your game to this project in the Google Play Console. See Figure 3 for the scheme.

    Then select “Android” to start linking an Android app. This is shown in Figure 3.

    [​IMG]
    Figure 3. Select the “Linked apps” in the left column. Your App ID is just below your chosen project name, and is indicated where with an orange frame. Choose “Android” as device. All others are not possible, since GameMaker: Studio doesn’t support them.​


    You will now see the following screen, see Figure 4.

    [​IMG]
    Figure 4. Linking an Android app.​


    Now we need to select a package name for the app. In case you plan to use the services directly in an already existing app, select it from the list by clicking in the box containing the small magnifying glass. But if you have no app yet, or you just want to test this out, we need to create a new app.

    This small paragraph is for users which want to create a new app. Open the spoiler to see how to create a new project, just for testing the tutorial.

    I think you already know how to do this, but I’ll quickly go through it.

    1. Select in the left menu the upper option, which is “Game services” which will redirect you to the main “Game services” screen.
    2. Then select “All applications” in the top left menu.
    3. Now choose for “Create application” somewhere at the top of the screen.
    4. Give as a title the future name of your game, I will choose “Tutorial Cloud Saving”.
    5. Then click “Create” and wait for a couple of seconds for your app to be created. We now need to add the APK to the Play Store. We don’t have one yet so we need to create it first.

    Hint: Make sure you have checked the box “Saved games” in the “Game details” tab of your project. In most cases this is done automatically.

    For now, we haven’t written a single line of code so we’ll do that first and then return to the Play Store to finish the job.

    Chapter 2: Setting up GameMaker: Studio

    Let’s head over to GameMaker: Studio to create an APK. Let’s create an object called controller and make this object persistent and put in into the very first room of your game. This is very important since the login in Play Games cannot be handled by us, so the exact time of loading is unknown, so the game should always be prepared to catch the response. You therefore need to make sure that the object is always available to catch this response.

    Now put the following code into the Create Event:

    Code:
    /// Initialise Google Play Games
    
    // Google Play Games
    if achievement_available() achievement_login();
    if achievement_login_status() show_message_async("Google Play Games login OK");
    
    // Load Dsmap
    scr_dsmap_load();
    
    // Initialise check variables
    cloud_check_file = 0;
    save_check_file = 0; 
    
    This will autologin the player and show a message when the login was successful. Furthermore, a script called scr_dsmap_load() is called. This script loads the user data from a securely stored .dat file. The script is shown below.

    Code:
    ///scr_dsmap_load()
    //
    // Script:      Loads the user data from a ds_map file
    // Date:        2018-08-07
    // Copyright:   Appsurd
    
    // Define variables
    global.topscore = 0;
    
    if (file_exists("dsmap.dat"))
    {
        var map = ds_map_secure_load("dsmap.dat");
    
        // Load data if it exists
        if (ds_map_exists(map, "topscore"))      global.topscore = ds_map_find_value(map, "topscore");
    
        ds_map_destroy(map);
    }
    
    // Save the data again to prevent loss of data
    scr_dsmap_save();
    
    You can use this script as an advanced version of ini files. The script initialises the global.topscore in case there is no file. But if there is a file, a check is ensured to see if the wanted variable was saved in the .dat file. If this is true, the global.topscore gets updated by the value in the file.

    Note that this script uses a new script called scr_dsmap_save() at the last line. As expected, this script saves all data to the .dat file. This script is shown here:

    Code:
    ///scr_dsmap_save()
    //
    // Script:      Saves the user data in a ds_map
    // Date:        2018-08-07
    // Copyright:   Appsurd
    
    var map = ds_map_create();
    
    ds_map_add(map, "topscore", global.topscore);
    
    ds_map_secure_save(map, "dsmap.dat");
    
    ds_map_destroy(map);
    
    This script saves all variables into the map. In case you wish to add more variables, be sure to define them in the load script, then add a line in the load script containing the ds_map_exists. And finally add a line in the save script to actually save the variable to the file. I won’t dive into details about these scripts, because I think they are rather straightforward to use. When you find it difficult, just don’t think about it and copy and paste them into your game :) In case you have any questions about it, please ask.

    Alright, we have set up the initialisation process. But we wish to receive something as well. Simply add the Asynchronous Cloud Event to the controller object and put in the following code.

    Code:
    /// Receive async messages from the cloud saving service
    if ds_map_find_value(async_load, "id") == cloud_check_string
    {
        if ds_map_find_value(async_load, "status") < 0
        {
            show_message_async("Cloud Services not available.");
        }
        else
        {
            if ds_map_find_value(async_load, "status") == 0
            {
                // Saving a string
                var data = ds_map_find_value(async_load, "description");
                show_message_async("String loaded data: "+string(data));
                
                global.topscore = real(data);
                scr_dsmap_save();
            }
        }
    } 
    
    This small piece of code handles all communication from the Google Play Services to your game. In case something went wrong, the message “Cloud services not available.” will be shown. Note that this does not necessarily mean that you have no internet connection. Whenever you did something wrong in the setup or you forgot to enable yourself as a testing user (this will be explained in chapter 3) you will also get this message as a response.

    Whenever the return is correct, the response will be saved in the variable global.topscore and after that, the file is saved on the device. This completes the code in the controller object.

    Now we wish to make two buttons: one for saving the variables from the game to the cloud and one for synchronising the data in the cloud with the game (which is the same as downloading the variables from the cloud into the game). Let’s start with obj_button_synchronise_string. Just create a sprite and create a Left Released Event. Put in the following code.

    Code:
    /// Synchronise with the cloud
    with (controller) 
    {
        cloud_check_string = cloud_synchronise();
        show_message_async("cloud_check_string = "+string(cloud_check_string));
    } 
    
    This synchronises (which actually means: downloads) the variables from the server to the game. The response of this request is handled by the controller object in the Asynchronous Cloud Event we just created. And that’s it for this object. Now create obj_button_save_string and add another sprite to the object. Then make a Left Released Event for the object and put in the following code:

    Code:
    /// Save the data
    with (controller) 
    {
        data = get_string("Enter score to save", "");
        save_check_string = cloud_string_save(data, "test data for cloud save");
        show_message_async("save_check_string = "+string(save_check_string));
    } 
    
    This asks the user to input some data (in your game, this is not what you want, you simply want the topscore or something like that to be send to the server and not direct user input ). Then this is saved to the server and the asynchronous test message is displayed. And well, that’s it for the actual coding.

    But we need to enable the Google Play Services in our project. Therefore go to the Marketplace and download https://marketplace.yoyogames.com/assets/2008/google-play-services to add it to your project. In case you don’t know how to do this, look up the information on the forums or one of YoyoGames’s tutorials: https://help.yoyogames.com/hc/en-us .

    Now head over to the Global Game Settings and click the Android section. Then select in the left menu the “Social” tab. Now check the button “Enable Google Services” is checked and also the button “Enable Google Cloud Saving”. Below that, enter the App ID which we extracted from the Google Play Console and copy paste it in. See Figure 5.

    [​IMG]
    Figure 5. The Global Game Settings in GameMaker: Studio, the Android / Fire tab. Click “Social” on the left. Be sure to check both boxes in the orange frame and enter your App ID as we found in the Google Play Console.​


    And that’s it for the GameMaker Studio side. Now compile your app for Android and save the APK as we will need it later on. Now let’s continue to finish the job.

    Chapter 3: Setting up the Google Play Console part 2

    Since we created an APK, we can start uploading it to the Google Play Console. Go back to your Dashboard and select your app, in my case “Tutorial Cloud Saving”. Then select “App releases” from the left menu. We need to upload an APK but users should not be able to see it, so under “Open track” click on “Create open track”. I already created one, but it should be on the spot indicated in Figure 6.

    [​IMG]
    Figure 6. Select “App releases” in the left menu and then choose “CREATE OPEN TRACK”.​


    Then select “Create release” and upload the APK. There is no need to enter any pictures or descriptions, since the app won’t be published. Now go back to the “All applications” in the top left corner and select the “Game services” again. Now select your project name and select the “Linked apps” again as shown in Figure 3. Then choose “Android” and select the right “Package name”, in my case: com.appsurd.cloudsaving. Now click “Save and continue” at the top of the page.

    You are prompted to authorise your app. Simply click “Authorise your app now” and follow the instructions. Don’t forget to copy the Sha-1 code and save it, I’m not completely aware of what it’s used for, but you can save it anyway.

    Now your app is ready for testing! Select “Testing” in the menu on the left. Now add your own email address with which you login to the Google Play Games to the testers list. Press “Continue to next step” at the top of the page to continue and save the mail address. The Google Play Console will show you a message that your app is not ready to be published since it contains no images, description, etc. This is no problem, just ignore it.

    Now transfer your APK to your phone and install it. Now let’s start testing if the app works.

    Step 1. Open the app and login with Google Play Games.
    Step 2. Click the save button to send your data to the server.
    Step 3. Exit the game.
    Step 4. Remove the app.
    Step 5. Reinstall the app.
    Step 6. Open the app again, and login again.
    Step 7. Now press the synchronise button to download the content from the server. You should now receive the data you entered in step 2. If you followed the tutorial correctly, the procedure should work :).

    I would love to provide you with a sample APK to test the functionality, but I would need to add your mail address by hand for every user separately and I’m not keen to publish such a sample app on the Play Store, so I’m afraid you have to follow the tutorial by yourself and implement everything before you can test it. However, I do have a sample project which you can download directly and see the code instead of having to type it yourself. It can be downloaded in the Marketplace: https://marketplace.yoyogames.com/assets/5485/cloud-saving-example.

    In the next chapter, I will discuss the practical implementation of the Cloud Saving in your app and how you can handle it.

    Chapter 4: Cloud Saving in practice

    I want to stress that the content of the first three chapters completely covers the actual working of the cloud saving procedure. But in this last chapter, I want to address several concrete steps to implement this system into your game.

    The first issue one could observe is that the standard method saves a string to the database. Although this is fine, this is inconvenient in practise. Mostly, your game is bigger than only one variable, so you would need to concatenate all those variables and separate them by a special character like “@”. Then save the whole string to the server. And when synchronising, you would need to split the complete string again on the special character, e.g. “@” and extract all data again. You could do the splitting by using https://marketplace.yoyogames.com/assets/4069/simple-string_split-script ). I personally find this inconvenient, but there are other methods too.

    Normally, you also save all variables locally to a INI file, ds_map file or something like that. So why not use json_encode() to convert your file to a string and send it to the server? And when synchronising, use json_decode() again to get it back?

    But there is an even easier option, that is by using cloud_file_save(). You require to edit some of the previous code, so I’ll quickly show it to you. It is shown in the spoiler below. PS: In case you want to spend your time a little more useful, don’t waste it to copy this code but simply head for the Marketplace to download the example belonging to this asset. It contains both methods, so no need to copy anything manually: https://marketplace.yoyogames.com/assets/5485/cloud-saving-example

    You can test these scripts in the same way as for strings, see section 3 for the complete procedure.

    In the controller object, change the Create Event to

    Code:
    /// Initialise Google Play Games
    
    // Google Play Games
    if achievement_available() then achievement_login();
    if achievement_login_status() show_message_async("Google Play Games login OK");
    
    // Load Dsmap
    scr_dsmap_load();
    
    // Initialise check variables
    cloud_check_string = 0;
    cloud_check_file = 0;
    save_check_string = 0;
    save_check_file = 0;
    
    Change the Asychronous Cloud Event from the controller to

    Code:
    if ds_map_find_value(async_load, "id") == cloud_check_file
    {
        if ds_map_find_value(async_load, "status") < 0
        {
            show_message_async("Cloud Services not available.");
        }
        else
        {
            if ds_map_find_value(async_load, "status") == 0
            {
                // Saving a file
                var data = ds_map_find_value(async_load, "description");
                show_message_async(data);
                
                var file = file_text_open_write("dsmap.dat");
                file_text_write_string(file, data);
                file_text_close(file);
                
                scr_dsmap_load();
            }
        }
    }
    
    Change the Left Button Released from the obj_button_synchronise_file to

    Code:
    /// Synchronise with the cloud
    with (controller) 
    {
        cloud_check_file = cloud_synchronise();
        show_message_async("cloud_check_file = "+string(cloud_check_file));
    }
    
    And finally, change the Left Button Released Event from the obj_button_save_file to

    Code:
    /// Save the data
    with (controller) 
    {
        global.topscore = get_string("Enter score to save", "");
        scr_dsmap_save();
        save_check_file = cloud_file_save("dsmap.dat", "Just for testing");
        show_message_async("save_check = "+string(save_check_file));
    }
    

    The next issue you run into is the moment when to save and when to synchronize. In my opinion, you should always save whenever something (big) changed (don’t save multiple times per second, but once in ten seconds is fine). But the loading option is different. In my opinion, you have two main options: always loading at launch of the app (and possibly even in between switching to the menu or so) or only on user request.

    Loading at launch or more often (Example: Bloons Monkey City, https://play.google.com/store/apps/details?id=com.ninjakiwi.monkeycity )
    Loading the data from the cloud at every launch of the app or even more often, has the advantage that you can check whether incompatibilities occur between client (your app) and server (the cloud saving database). You can add a timestamp to see which variables are the same as the server version and client version and which are different. You may also check if a user has cheated if his number of coins has increased by a million in one minute, for example. A clear disadvantage is that you need to develop a system for this checking method, and this will take time and will never be perfect. For example, what to do if the user saved data is different than the data on the cloud? Did the user have no internet connection? Did the user cheat? Did the app crash or maybe even the cloud service? All these questions are far tougher to answer than most of us would want to think about. So there’s another option.

    Loading on user request (Example: King of Thieves, https://play.google.com/store/apps/details?id=com.zeptolab.thieves.google )
    What if you would only load the data upon user request? Typically, a user would request the data to be loaded if he/she switched device, or rebooted his phone because of (un)known reasons. Programmatically, this is also super easy, just add a button for it in the settings menu and you’re done. Some disadvantages include the not being able to check for cheating, as loading is only done on user request (note that cheating not only includes the adding 1M coins to his account but also includes a user decision which was not smart (for example, your app includes a mystery box and the user bought it 100 times but got nothing. He then decides to quickly load the data to prevent him from losing his money for the boxes)). This last example can possibly be prevented by saving at every change in the game, but calling the cloud saving extension more often than once in ten seconds is not preferable, and I also don’t know in which time interval the string / file on the cloud saving server changed so that, on the next call, you receive the updated version, but I can imagine this not being instantaneously, so you could load older versions on a quick press on the loading button.

    The content in this section is open for discussion, so feel free to post your opinion on the matter in the discussing section below!

    Conclusion

    The tutorial is finished by now, I hope you learned how you can implement cloud saving on Android devices using the Google Play Console and how to implement it in GameMaker: Studio. If there are any questions or if you find anything unclear, please post your response in the comments below. Thanks for reading the tutorial and have fun with your cloud saving system!

    Error solving: Common issues

    Here is a short list of some common mistakes.

    - Make sure you have checked the box “Saved games” in the “Game details” tab of your project in the Google Play Store.
    - Fill in the App ID in GameMaker’s Global Game Settings.
    - Enable yourself as a testing user to be able to use the Google Play Games in the Google Play Store.

    Changelog

    Changelog, huh? Yes, it’s actually just for me to check when and what I changed in the tutorial. Any people contributing something will be added too. :)

    V1.1.1 (2018-08-10)

    - Added extra async message in project
    - Small text fixes

    V1.1.0 (2017-07-15)

    - Included extra information about the possibility to save files and multiple variables at once
    - Improved example code downloadable from the Marketplace explaining both saving strings and files
    - Added common issues
    - Small text fixes

    V1.0.0 (2017-05-30)

    First English version of the tutorial was written.
     
    Last edited: Aug 10, 2018
  2. Millionsknivez

    Millionsknivez Member

    Joined:
    Jan 15, 2017
    Posts:
    45
    I'm having some issues with finding the filename when saving and loading could you help me out?
    Also can you describe how to use the achievement login? I'm getting network errors ><
     
    Last edited: Jun 21, 2017
  3. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    I will answer your private message instead
     
  4. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Changelog V1.1.0 (2017-07-15)

    - Included extra information about the possibility to save files and multiple variables at once
    - Improved example code downloadable from the Marketplace explaining both saving strings and files
    - Added common issues
    - Small text fixes

    Download the example now for free from the Marketplace: https://marketplace.yoyogames.com/assets/5485/cloud-saving-example
     
  5. Qual

    Qual Member

    Joined:
    Aug 16, 2016
    Posts:
    29
    Did you find any way to tell the user if the commit was successfull ?
     
  6. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Unfortunately, you cannot. I tried to catch it the same way as the real string is returned, but that doesn't work. In general you may assume that, if your internet connection works (os_check_is_connected) the request is send properly. If someone knows how to do this, please respond to this topic :)
     
  7. RATInteractive

    RATInteractive Member

    Joined:
    Jun 29, 2016
    Posts:
    128
    About to have a go at this, been wanting to do this for ages. will let you know if i'm successful

    Have you considered doing an IAP tutorial for android, most tutorials are highly outdated.

    - Ross

    Edit: i've been looking at the tutorial though i haven't finished it yet, it is annoying that you decided to have a key input when saving, rather than demonstrating how you would save values such as coins collected rather than a custom amount.
     
    Last edited: Jul 29, 2017
  8. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Yes I have, but I probably won't, at least not in the near future. The documentation on the topic is in my opinion very clear, so you should be able to figure it out yourself. Also read Yoyo's tutorial about the matter https://docs.yoyogames.com/source/dadiospice/002_reference/in app purchases/index.html and this page https://help.yoyogames.com/hc/en-us/articles/216755198-In-App-Purchases-Example

    I understand your point, but I have to disagree with you. I wrote this tutorial for advanced users, who should be able to figure that out themselves. Although Cloud Saving isn't the most difficult part of programming, the documentation was unclear, therefore I wrote a tutorial. The reason I chose for the 'annoying' thing is that you are now more easily able to test the functionality of the program to see if it works. If you have any further questions, don't hesistate to post them here and I'll be happy to answer them. :)
     
    chirpy likes this.
  9. RATInteractive

    RATInteractive Member

    Joined:
    Jun 29, 2016
    Posts:
    128
    I hadn't looked into the yoyo ones yet as sometimes their own tutorials have errors in.

    id assume the code would look something like this

    Code:
    with (controller)
    {
        data = global.topscore
        save_check_string = cloud_string_save(data);
        show_message_async("save_check_string = "+string(save_check_string));
    } 
    Maybe i'm wrong, I wasn't saying it in a moaning way I just thought it was a strange way to do it
     
  10. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Yes, I know, that's very annoying. But in my memory this one works as it should. But I have to admit that I haven't used it for quite a long time.

    Exactly. And when you got the tutorial working, you can test this code quite easily to see if it's working :)
     
    RATInteractive likes this.
  11. RATInteractive

    RATInteractive Member

    Joined:
    Jun 29, 2016
    Posts:
    128
    Thanks will be able to test it tomorrow :)
     
  12. Zhanghua

    Zhanghua Member

    Joined:
    Aug 3, 2017
    Posts:
    132
    eh, thiat's only for google app store?
     
  13. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Unfortunately, yes. The Apple Store/iOS doesn't use Google Play Services (well, duh, of course since Apple and Google kinda hate each other ;)) but Game Centre. And I don't have a Apple device nor a Publisher account, so I can't test things out... So Android/Play Store only
     
  14. Zhanghua

    Zhanghua Member

    Joined:
    Aug 3, 2017
    Posts:
    132
    I meant to apply the method to the thirdpart android app store.
     
  15. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    I'm afraid I don't understand your question. Could you please explain it?
     
  16. Zhanghua

    Zhanghua Member

    Joined:
    Aug 3, 2017
    Posts:
    132
    Oh, sorry for that. My coutry baned the google service, there is only third party app maket, I'll test by your method firstly.
    If there might have any question, I'll ask you for help again, TKS.
     
  17. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Ah, I understand. You can try, but I expect it doesn't work. What is the name of this 'third party app market'?
    Also, if it doesn't, I can probably not help you...
     
  18. hackerG7

    hackerG7 Member

    Joined:
    Feb 21, 2017
    Posts:
    7
    Thank You so much! I tested it! Working pretty well.(Although I try a whole day cuz I'm an idiot) keep going bro!
     
  19. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Thanks mate :)
     
  20. chirpy

    chirpy Member

    Joined:
    Oct 6, 2016
    Posts:
    82
    Great tutorial! Thanks a lot.

    A bit off-topic but hopefully not too much: had anyone used / seen tutorials on amazon whispersync for cloud saving? I've heard it's also available for iOS, and I'm hoping it'll also work in China.
     
  21. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Thanks!
    You could take a look at this tutorial. I have no experience whatsoever with Amazon Gamecircle, so I can't help you out. And don't forget to download the right Marketplace asset as well

    EDIT: as per jan 2016, some issues where present: https://stackoverflow.com/questions/34888684/amazon-gamecircle-on-generic-android-device No idea if it is fixed though.
     
    chirpy likes this.
  22. JacPete

    JacPete Member

    Joined:
    Aug 24, 2016
    Posts:
    257
    Works flawless and is easy to modify and thanks for your help and asistance during the integration process @PeliStar, its a very nice feature.
     
  23. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    You're welcome and it's great you like it!
     
  24. Ernesto Romero

    Ernesto Romero Member

    Joined:
    May 12, 2017
    Posts:
    35
    hank you very much friend, I do not understand English very well but I have already integrated it, I only have a very silly question, what script should I modify to add another variable, I already have a saved .ini files and there are 200 variables my videogame is already finished, but I had difficulties to add the remaining variables, I leave my video game in google play: https://play.google.com/store/apps/details?id=com.rnetstudio.rnetgames
     
  25. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    I do not quite get what you mean. You have an ini file, so you can use cloud_file_save to upload your ini file, right?
     
  26. @Jizo

    @Jizo Member

    Joined:
    Jul 12, 2016
    Posts:
    33
    Hey there, I hope that you are reading this.. it's been a while since you've posted this tutorial.
    I've tried to get cloud saving working by following your example. I've encountered few problems/questions:
    1) I've followed all of the steps but the game crashes immediately after I click my "cloud save" or "cloud load" -buttons. The console shows a message "FATAL EXCEPTION: AsyncTask #1". This started after I input all the information to Google Play Console, enabled save, added game ID to Game Maker, it started crashing every time. I am using newest version of Game Maker 2. What might be a problem?
    2) I'm quite new with async and dsmap -stuff. I didn't quite understandthis, so this example saves global.topscore but when clicking on "cloud save"-button, the code there saves
    data = get_string("Enter score to save", "") to cloud instead of global.topscore?
     
  27. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Sure I am, as you might have recognized from the post above yours :)
    Hmm strange, never encountered that error before. I still use GMS1.4 so I can't verify this unfortunately. I can't inspect your project file either... Perhaps someone else knows what is going on?
    No, this data = get_string() is only there for testing haha. So you can easily change this to see if the asset is working. In general, you will just put global.topscore there.
     
  28. Ernesto Romero

    Ernesto Romero Member

    Joined:
    May 12, 2017
    Posts:
    35
    Hello again, I do not speak English, but I will try to translate everything.
    I already implemented the "cloud saving for android" system, but I saved all my variables in the .ini file, is it possible to use .INI? enves de DS map
     
  29. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Yes, read the tutorial Chapter 4 under the spoiler.
     
  30. @Jizo

    @Jizo Member

    Joined:
    Jul 12, 2016
    Posts:
    33
    Thanks! I've now tried everything but it always crashes upon clicking save/load -buttons.
    So is Cloud saving working for you in GMS2.0 or do you use 1.4?
     
  31. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    I only have 1.4 :( So that's why I said, perhaps somebody else can check this out. So can't help you any further, sorry
     
  32. @Jizo

    @Jizo Member

    Joined:
    Jul 12, 2016
    Posts:
    33
    Ah right, thanks! I try to figure this out somehow :)
     
  33. Leonardo007

    Leonardo007 Member

    Joined:
    Dec 28, 2017
    Posts:
    8
    Hello, i did not work for me..... everytime if google play want to log in it says: no cennection, try again...
     
  34. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Strange...

    Are you certain you supplied the correct App ID in GameMaker: Studio?
     
  35. Leonardo007

    Leonardo007 Member

    Joined:
    Dec 28, 2017
    Posts:
    8
    yes i checked it, it was the right app id, but it doesnt work...
     
  36. Leonardo007

    Leonardo007 Member

    Joined:
    Dec 28, 2017
    Posts:
    8
    ok.... the keystore key was wrong... i got this, and now its logging on ;)
     
  37. Leonardo007

    Leonardo007 Member

    Joined:
    Dec 28, 2017
    Posts:
    8
    ok now i checked again your tutorial, made 2 buttons and the controller:


    I/yoyo (32632): Setting vis flags to 5894
    E/AndroidRuntime(30935): FATAL EXCEPTION: highpool[1]
    E/AndroidRuntime(30935): Process: com.google.android.gms, PID: 30935
    E/AndroidRuntime(30935): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
    E/AndroidRuntime(30935): at nyi.a:)com.google.android.gms@11951240:127)
    E/AndroidRuntime(30935): at sxj.run:)com.google.android.gms@11951240:11)
    E/AndroidRuntime(30935): at mwc.run:)com.google.android.gms@11951240:26)
    E/AndroidRuntime(30935): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    E/AndroidRuntime(30935): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    E/AndroidRuntime(30935): at nbl.run:)com.google.android.gms@11951240)
    E/AndroidRuntime(30935): at java.lang.Thread.run(Thread.java:831)
    I/yoyo (32632): onConnectionFailed called with result:ConnectionResult{statusCode=INTERNAL_ERROR, resolution=null, message=null}
    I/yoyo (32632): Setting vis flags to 5894
    I/yoyo (32632): onWindowFocusChanged(false|false)
    I/yoyo (32632): Setting vis flags to 5894
    W/yoyo (32632): AL lib: (EE) dlGetIID: dlsymIID :: SL_IID_VOLUME :: e1fc7edc
    I/yoyo (32632): Setting vis flags to 5894
    I/yoyo (32632): Setting vis flags to 5894



    i tried to uncheck google play cloud and he is lgging in... if i check it will make an error...
     
  38. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Okay, it seems like you correctly added the Google Play Services Asset from Yoyo. Since the keystore is correct as well, I cannot deduce from this piece of log where the actual problem is. Could you send me your project via a PM? Then I can take a look to see if you (accidently) made a programming error
     
  39. Leonardo007

    Leonardo007 Member

    Joined:
    Dec 28, 2017
    Posts:
    8
    yes i will do....


    do i have activate cloud in the google developer board? where its saved the file???
     
  40. Leonardo007

    Leonardo007 Member

    Joined:
    Dec 28, 2017
    Posts:
    8
    I/yoyo (15206): onConnectionFailed called with result:ConnectionResult{statusCode=INTERNAL_ERROR, resolution=null, message=null}
     
  41. Ernesto Romero

    Ernesto Romero Member

    Joined:
    May 12, 2017
    Posts:
    35
    I could make a small example with files. INI? tranks
     
  42. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Hi sorry for my late reply. I could do so, but I won't. First of all, using ds_map and secure saving is much more secure than using INI files. Hence it is preferable for more advanced users. Moreover, I aim this tutorial at intermediate/advanced users, so I hope these developers have some knowledge about INI files and saving. In other words, if you don't understand it in this way, I think you can manage yourself to change it to INI files. I understand this is not the answer you hoped for, but it would take me far too much time to comply with all of your wishes, sorry :(
     
  43. Ernesto Romero

    Ernesto Romero Member

    Joined:
    May 12, 2017
    Posts:
    35
    Thank you very much, I do not speak English, and this tutorial is difficult for me if I do it, so what should I do to save the variables in ds_map one by one?
     
  44. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    In scr_dsmap_load():
    Under define simply define all variables to ensure they actually exist. Example:
    Code:
    Like global.topscore;
    
    In scr_dsmap_load():
    In the for loop under load data if it exists, try to load the variable from the file if it exists. Example:
    Code:
    if (ds_map_exists(map, "topscore"))      global.topscore = ds_map_find_value(map, "topscore");
    
    In scr_dsmap_save():
    Below the load file, enter a file for each variable to save it. Example:
    Code:
    ds_map_add(map, "topscore", global.topscore);
    
     
  45. Reivaxcorp

    Reivaxcorp Member

    Joined:
    Apr 9, 2018
    Posts:
    1
    Don't working for me:

    In console appears:

    "cloudSynchronise called when not logged in to appropriate service"
     
  46. brice_platinum

    brice_platinum Member

    Joined:
    Oct 9, 2017
    Posts:
    1
    Hey, I have a question, in the manual it says:
    IMPORTANT! The secure saved DS map file can only be loaded on the device that created it, and if you try to load a file that was saved on a different device, then it will not work.

    Does thist means that if i want to move my save data to another device it will not work?, also do you know if this still works in GM2?
     
  47. zbox

    zbox Member

    Joined:
    Jun 21, 2016
    Posts:
    765
    Secure DS maps only work on the one device but it's easy to get around - I've just used a different method to encode/obfuscate my app's data. Save it to a string and run an encryption cypher on it, that way you're totally in control and it offers just as much security as the ds_secure function.
     
  48. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Hi there, awesome you tried the tutorial and it's a pity you couldn't get it to work. I have never experienced this before, are you certain you created the right project in Firebase? If so, you may contact me personally as well, so I can (possibly) help you out.

    For your first question, @zbox has supplied a perfect answer, thanks!
    For your second question, I have no idea :( I haven't been able to purchase GMS 2 due to the high price and my limited funds, so I have no idea if it works without any changes. Perhaps some other user can help us out?
     
    zbox likes this.
  49. zbox

    zbox Member

    Joined:
    Jun 21, 2016
    Posts:
    765
    For Android, my asset CloudSave uses the internal GM cloud saving functions at its core and it does work with GMS2 :) iOS is a different story though
     
  50. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Seems interesting, however, I wrote this tutorial for starting users to get some feeling of the subject. And comparing a free tutorial and a $40 asset is not really fair ;)
    One day I will make this available for GMS2, but I really can't say when..
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice