According to the GPGS website-
Use the client libraries. The mobile client libraries employ a number
of strategies to reduce the calls you make to the service. For
instance, achievement and leaderboard data is cached, so a user can
view their achievements as often as they'd like without requiring the
service to make multiple calls. Both the Android and iOS client
libraries will know not to send a player's score to the server if
your score isn't as good as one you recently submitted. The Android
library also automatically combines frequent achievement increment
calls when it detects that you are being rate limited.
I'm specifically interested in 'viewing achievements without requiring the service to make multiple calls'. As far as I can see, the best way to do this would be to use the OnAchievementsLoadedListener and get a reference to the achievementBuffer.
Will that buffer be updated when an achievement state is changed and is it okay not to close that buffer immediately? If not, the OnAchievementsUpdatedListener does not pass a buffer or even and indiviudal achievement reference so how would I get the updated collection of achievements?
I found my answer here:
https://developer.android.com/reference/com/google/android/gms/games/GamesClient.html#loadAchievements%28com.google.android.gms.games.achievement.OnAchievementsLoadedListener,%20boolean%29
Set forceReload argument to false to gain the advantages of data-caching :)
Related
I am thinking of using RemoteConfig for these 2 purposes:
Have on the server a parameter minVersion of the app that should function. So for instance if v1.5 is broken and I release an update on Google Play as v1.6 I want to block access to 1.5 and older and force the user to update to 1.6 in order to use the app.
Have on the server, a parameter to store a message to display in the app. So for instance have a message like "We are having server maintenance, please wait a while". On app start, if the message parameter is not empty, show a dialog with it in the app.
Of course, in this case, on each app start I need to fetch the remote config values and check them.
Why use RemoteConfig? Because it's easy, it's free, it's convenient and I don't need to have another separate server for these 2 simple jobs.
So is this a valid use case?
Yes these are both valid cases.
For point 1, you can quite easily determine the users app version. I created a video detailing how to do it
https://youtu.be/McP11kcrMtk
I want to use cloud storage for my game for 3 platforms. So you can play on the web, then continue on your mobile for example.
I am looking at the API documentation, and I can only see support for getting snapshots. I want to create a new snapshot and then save it. It shows how to do this for mobiles but not web?
Surely the service doesn't limit you in this way. It would destroy the user experience.
Thanks,
Shaun.
Unfortunately as you know there is no API to write a Saved Game using the web API. If you want to support web and mobile game saving, you'll have to implement it yourself. An easy way to do that is to use the Application Data Folder for Google Drive. This allows your application to store data in a hidden directory on the player's drive account. This API is also available on Android (https://developers.google.com/drive/android/appfolder) and even iOS (https://developers.google.com/drive/ios/).
What you miss out on by not using the Play Game Services is primarily some caching logic on the client and the user interface for selecting the snapshot. If you eliminate the caching logic, you also eliminate the need for complex conflict resolution (assuming you use a 'last write wins' approach)
At a high level the steps would be:
Create a new application on the Google API console for the platforms you want to support.
Implement login in your game (this would be the same as if you are using Saved Games via Play Game Services.
Use the specific client Id for the correct platform to access the app data for your application.
Implement a UI to select an existing snapshot or create a new one.
Here, you create the savegame by name if not exists:
Snapshots.OpenSnapshotResult open = Games.Snapshots.open(
mGoogleApiClient, name, create).await();
if (!open.getStatus().isSuccess()) {
throw new RuntimeException("or whatever");
}
Snapshot snapshot = open.getSnapshot();
snapshot.getSnapshotContents().writeBytes(mySaveGame);
create is a boolean telling you want to create a new one when it does not exist.
name is the savegame name.
mySaveGame is my binary blob to be stored.
As I understand your question, there are the following scenarios possible in your example
Player playing on mobile, saved the game, accessed the game next time on mobile
Player playing on mobile, saved the game, accessed the game next time on Web
Player playing on Web, saved the game, accessed the game next time on mobile
Player playing on Web, saved the game, accessed the game next time on Web
I am assuming your game has complex logic requiring client-server implementation. And given the discussion above, I am assuming you want to save the game in Google Play Game Services (as opposed to your own web Server).
In this case, for scenario 1 and 3 above, you will retrieve the Snapshot as demonstrated in the answer by eduyano earlier.
Snapshots.OpenSnapshotResult open = Games.Snapshots.open(
mGoogleApiClient, name, create).await();
if (!open.getStatus().isSuccess()) {
throw new RuntimeException("or whatever");
}
Snapshot snapshot = open.getSnapshot();
snapshot.getSnapshotContents().writeBytes(mySaveGame);
However, for scenario 2 and 4 above, you will need to use the REST API services for 'Play Games Services for Web'.
So first you will have to make the HTTP request to get the Player ID
GET https://www.googleapis.com/games/v1/players/playerId
Subsequently, you will need to know the Snapshot IDs saved against this Player. So make another HTTP request
GET https://www.googleapis.com/games/v1/players/playerId/snapshots
For the Snapshot ID retrieved, make the HTTP request to retrieve the relevant Snapshot. It will need authorisation. At this point a JSON object corresponding to the saved Snapshot will be returned.
I hope this helps... And I am assuming you will know how to load the snapshot once the JSON object is returned. Feel free to ask for further clarification.
More details at https://developers.google.com/games/services/web/api/snapshots
In my game I use Google Play Game for Achievements and Leaderboards.
I've just noticed (by logging into the Google API Console), that performing a simple action such as displaying a leaderboard, results in 2 API calls. I would have thought this would be only 1.
I'm simply calling the leaderboard like so:
public void displayLeaderBoard(){
if (getGameHelper().isSignedIn()){
if (leaderboardIntent==null){
leaderboardIntent = Games.Leaderboards.getLeaderboardIntent(getApiClient(), leaderboardID);
}
startActivityForResult(myLeaderboard, 1);
}
}
Note it is still 2 API calls even when pressing the leadeboard button a 2nd time (therefore not creating a new 'leaderboardIntent').
Also, when submitting a high score, it uses 3 API calls (one for submitting, then again it calls displayLeaderboard() to show the player her/his new high score.
The thing here is if I then exit back to the app and submit the score again, it uses another 3 API calls. The documentation states:
Both the Android and iOS client libraries will know not to send a
player's score to the server if your score isn't as good as one you
recently submitted.
I know I could simply store a copy of the high score in sharedPreferences and then not submit it if it's not high enough, but I'm not sure about this - what if the device has multiple accounts set up for example.
I would be grateful if someone with more knowledge/experience of the Play Games API could confirm if the number of API calls I'm seeing is correct and how this relates to quote above, or whether there is something more I should be doing in my code?
The number of calls you are seeing could very well be correct. For many APIs, each request has a "cost" related to it. Which means where a read request to a certain API might cost you 1 call, a write request might cost you 5 (just assuming). Hence, depending on the requests you are making your number of calls are going to differ compared to the number of requests made. For example, try this tool to calculate Youtube API quota cost. Unfortunately I couldn't find any such tool or documentation for Play Games Services API but I hope this makes my point clear.
For optimizing your code to perform it's best, take a look here and try to optimize your code to follow Best Practices as much as you can.
I am planning on introducing Google play game services to my app. However I am not sure if i can provide the following capability. I need to be able to list the rooms available so the player can join any room he chooses rather than auto join.
Is there a way to do that? Thank you
In the current implementation of our API, there are no "open rooms" that you can voluntarily enter. You need an invitation to enter a room. So the method we have that's closest to what you're asking is the GamesClient.loadInvitations() method, which will list all the currently active invitations to rooms that the player has.
If the behavior you're trying to implement is "I want to join a room that's playing upside-down four-dimensional chess", without being specifically invited by a friend, then what you want is probably automatching. Automatching means you create a room and specify the number of players you want in your game and, optionally, a variant code (an integer) that indicates the game type. Then, the API will match together a set of players who is wanting to play that same variant at that moment, and will put them all in the same room.
You might need to use Leaderboards in Android
I can't see how you could do this in the current release of Game Services (at least not if you use the API in the way that Google wants you to).
However I just noticed this:
https://developers.google.com/games/services/web/api/rooms/join
Join a room. For internal use by the Games SDK only. Calling this
method directly is unsupported.
Maybe this sort of thing will be possible at a later date ?
I'd like to have an android app that would allow a given number of users to be "logged in" either as a player or ref. The players would just be able to increment their score, while the ref would have a screen that shows all player scores and alerts the ref with a tone/vibration when a player reaches a target score.
I have no android dev experience and in a perfect world I would just find an app that does something similar to this that I can just tweak. I'm not sure if this kind of functionality would depend on having a server or at all where to begin on learning the knowledge that would be necessary to create such an app.
Kind of a vague question... you will however need a server to keep track of all the scores - for example you can have an SQL database that contains all the users/scores and all the Android app is tell the server which user's count to increment.
Another alternative would be to use the Google Drive APIs - you can probably use forms or something to increment counts while the "ref" would have full access to the document.