Google Play Game Services few questions

I get this error/crash when script gets message “set_data” and tries to execute save_data(Crashes when tries to commit and close).
I’ve tried to use update function with checking if player lost but the game still crashes.

I don’t have enough information to understand what’s the cause of the crash.
Would be nice if you could provide full log (not only one application) from logcat and _crash file (Successfully wrote Crashdump to file:/data/user/0/com.CrossMan.todo/files/_crash)

I managed to get google cloud save work!
For those who get trouble integrating it, here are my tips :
I followed AGulev’s example and made this working code :

local use_saved_games = sys.get_config("gpgs.use_saved_games") == "1"

local function open_snapshot()
	gpgs.snapshot_open("googledata", true, gpgs.RESOLUTION_POLICY_MANUAL)
end

local function save_data(highscore)
	local success, error_message = gpgs.snapshot_set_data(highscore)
	if success then
		print("COMMIT IS SUCCESSFULL")
		gpgs.snapshot_commit_and_close() --would be better to set data for the automatic conflict solver
	else
		print("snapshot_set_data ERROR:", error_message)
	end
end

local function callback(self, message_id, message)
	if message_id == gpgs.MSG_SILENT_SIGN_IN then
		if message.status == gpgs.STATUS_SUCCESS then
			open_snapshot()
		else
			gpgs.login()
		end
	elseif message_id == gpgs.MSG_SIGN_IN then
		if message.status == gpgs.STATUS_SUCCESS then
			open_snapshot()
		else
			print("can't login")
		end
	elseif message_id == gpgs.MSG_LOAD_SNAPSHOT then
		print("MSG_LOAD_SNAPSHOT")
		if message.status == gpgs.STATUS_SUCCESS then
			print("STATUS_SUCCESS")
			local bytes, error_message = gpgs.snapshot_get_data()
			if not bytes then
				print("snapshot_get_data ERROR:", error_message)
			else
				highscore = bytes
				print(highscore)
				print("snapshot_get_data", bytes)
				-- if we have the not saved data, let's try to save it
				if self.not_saved_data then
					save_data(self.non_saved_data)
					self.not_saved_data = nil
				end
			end
		end
	end
end

function init()
	if gpgs then
		gpgs.set_callback(callback)
		gpgs.silent_login()
	end
end

function update(self, dt)
	if gpgs then
		if self.is_logged_in ~= gpgs.is_logged_in() then
			self.is_logged_in = gpgs.is_logged_in()
		end
		if use_saved_games then
			if self.snapshot_is_opened ~= gpgs.snapshot_is_opened() then
				self.snapshot_is_opened = gpgs.snapshot_is_opened()
				print("snapshot is opened")
			end
		end
	end
end

function on_message(self, message_id, message, sender)
	if message_id == hash("set_highscore") then
		if gpgs then
			if gpgs.snapshot_is_opened() then
				print("snapshot is opened and trying to save highscore")
				save_data(highscore)
			else
				print("snapshot isn't opened")
				-- your snapshot has already closed (or wasn't open)
				-- let's save your data locally in `self` and try to save it when the snapshot will be opened again
				self.not_saved_data = message.data
				open_snapshot()
			end
		end
	end
end

function final(self)
	if gpgs then
		gpgs.logout()
	end
end

Don’t forget that : gpgs plugin return value as raw bytes as string.
So if you get an error that you compare number with string just simply use : tonumber(highscore) .

Also I used to get crashes when trying to execute save_data() function specifically after trying to run gpgs.snapshot_commit_and_close(), because of not specifying the data which should be saved.

1 Like

I published an update with working gpgs. But now after I launch my game I get google play login/connecting bar, but it doesn’t successfully login. Why does this happen? Do I need to get user id or something? Can it be that I enabled anti-piracy option? Also ads doesn’t work now too.

Ok after a while ads started to work again but login doesnt work. It just says google play connecting.

For those who have similiar problem, follow these steps :

  1. Go to Google Developer Console

  2. Click All Applications > Your Application

  3. Go to Release Management > App Signing

  4. Notice there is an " Upload Certificate" and an " App Signing Certificate".

  5. Copy the SHA1 from the APP SIGNING CERTIFICATE.

  6. Click All Applications on the Top Left, then click Game Services > Game Details

  7. Scroll all the way down and look for
    API Console project
    This game is linked to the API console project called ‘YOUR APPLICATION NAME SHOULD BE HERE’

  8. Click on your application name at this location.

  9. Now you’re in the API’s & services. Click on Credentials

  10. Edit your OAuth 2.0 client ID.

  11. COPY THE SHA1 FROM THE APP SIGNING CERTIFICATE HERE AND BE SURE YOUR PACKAGE NAME IS CORRECT.

1 Like

@AGulev
is it intended that gpgs.snapshot_commit_and_close() fires gpgs.MSG_LOAD_SNAPSHOT ?

No, it’s not
gpgs.MSG_LOAD_SNAPSHOT - The message type that GPGS sends when finishing the asynchronous operation after calling gpgs.snapshot_open() (Defold Google Play Game Services documentation description for gpgs.MSG_LOAD_SNAPSHOT)

sorry, was not clear enough with my question,
it’s obvious when msg’s are fired but i asked if it’s intended because in my code it does what i mentioned and i know that it can’t be right.
Take your sample code from above, when the snapshot is loaded and i call save_data(...) i get response from MSG_LOAD_SNAPSHOT and so snapshot_get_data() is called again without a loaded snapshot.

I’ve been testing cloud save for a while with different accounts, phones. And I get the same crash, I used to get. I know that you need more information, but I can’t find crashdump file. I can’t find the given path. And is it in the computer or android device? I send you text document of the logcat.
And as you can see after snapshot_get_data there aren’t any bytes value? Maybe this might cause the crash? Do I need to declare bytes? Currently I have like this :

local bytes, error_message = gpgs.snapshot_get_data()
			if not bytes then
				print("snapshot_get_data ERROR:", error_message)
				save = false
			else
				highscore = bytes
				print("snapshot_get_data", bytes)

I really feel bad for asking too much… Sorry…
log.txt (3.1 KB)

P.S What is really strange is that when I release beta version, on other device and google account it works, no crashes. On mine it works perfectly too, on my mom’s it always crashes.

2 Likes

Don’t worry, everything is fine. Feel free to ask your questions, we are happy to help our users.


Do you have adb on your machine? If yes, just run in the terminal this command to download file from your phone:
adb pull /data/user/0/com.CrossMan.todo/files/_crash crashfile

And could you send full logcat log? (adb logcat -f logcat.txt)

I would like to help you but I can’t find any useful information in your current log and can’t reproduce this crash on my device.

3 Likes

I get error after running this command. Permission denied. Do I need to root my device for that?
Also when I use the debug apk of my game it crashes, but when I download the beta version from google play it doesn’t crash.

Make sure the app is debuggable (it should be, unless you’ve bundled a release build).

Then you can get it like so:

$ adb shell "run-as com.CrossMan.todo sh -c 'cat /data/data/com.CrossMan.todo/files/_crash'" > ./_crash
1 Like

I wrote this command, but it returns : package not debuggable: com.CrossMan.todo
Although I bundled it as a debug variant…

Update : I noticed that I haven’t selected debuggable in the game.project. Testing it now…
Update Update : It still returns : package not debuggable: com.CrossMan.todo

I beated the highscore in the beta release on google play (I don’t get crashes there); I debugged new apk and the highscore is correct, so it means that the Cloud Save works perfectly. But I get crashes when on debug version it tries to commit and close. (On my friends device, he got crashes on the beta release version tho)

And what about the log file, did you get that?

No. I can’t get that file too.
Also why does my project is named project-*** instead of the name of the app) in app permission site?


And I noticed in my game it requires google drive permission, but in other games it only requires access to google play, and in those games they still save the data in the cloud?

I’ve signed in with my google play account to my mom’s device, and it still crashes with my google play account. But it works perfectly on my device with my google play account. Can it be something with local data? I also use defsave in my game to store data locally.

They use Google Play only for identifier, but save data using their own servers or external services. For example, @Dragosha in “Look, Your Loot!” uses Playfab for the game saves.

2 Likes

Another question.
In your example you used :

 gpgs.snapshot_commit_and_close({progressValue = get_progres_value()})

Do I need to declare variables progressValue or make a function get_progess_value() or does it understand all by itself?

Also do you have any clues why it crashes on my mom’s device but works on mine with the same google account? And also it crashes on my friends device with his account; But everything works perfectly on my dad’s device with his account? Can it be local data? Or is it because I haven’t done auto problem solver?

I don’t know. It could be everything. I don’t have enough data to answer your question.

This is just an example.
Method snapshot_commit_and_close(metadata) has a parameter which is a table that contains 4 values. You could read about them in the documentation. All those parameters are optional, but I recommend to set at least one of them to make it possible to recognize your save and solve a conflict if it happens.

Yes, but should I declare progressValue? How should I increment it? Does it automatically do the work if I leave just like that?

Yes, you should.
It could be any number that represents a player’s progress. It depends on your game: percentage of game progress, level number, a total score, etc.