• Forum
  • Android Game not working correctly if exported with debug is disabled

Hello I just finished a mobile game, I can test it directly from Godot in my phone and I can make a custom build .apk file with the option "export with debug" enabled and install it on my phone and everything works fine (using the debug keystore), I can build a custom export .apk and .aab file with the option "export with debug" disabled successfully (using the release keystore), and even upload the .aab file to the Google Play Console, but when I install and test the "release" .apk file on my phone or try the .aab version installed via Google Play, the game can be played but there are a lot of bugs related with the persistent data that is stored and loaded from a resource .tres that is created on the path "user://". I don't know what I'm missing, on the debug .apk version the data is stored and loaded correctly, I am using Godot 3.4, any insight will be highly appreciated. Thanks.

a month later

Can you give an example/error/bug?

The player level data appears to be correct, the levels are working according to the player level, and if I printed it on a debug label on the screen the number is correct, but there is a condition at the end of each level that triggers the end of game animation when the player level is equal to the number of levels and the animation is triggered every time at the end of the level no matter what the player level is. Also the screen shader colors should change according to the player level but they get stuck on the same color, the first level color.

All of that works correctly if the option "export with debug" is enabled, so I build export templates with the target=debug and another to the target=release_debug , I tried them both with no success, the same bugs occur if the "export with debug" option is disabled.

Thanks!

Debug has access to additional storage areas that should not be accessible on a released game. For example, loading files manually from res:// or other things. The Android permissions may also be part of the problem (you need file permissions to access user folders for certain things). Honestly, the user data folder is for saving text files, for example save games or config options. Not for animation or visual effects.

8 days later

Ok, after refactoring now its working correctly! the persistent memory wasn't the problem, sorry for the confusion I am learning programming with Godot, this is my first game!! :)

The variable current_level is declared as an int on the singleton Vars which contains shared variables between scenes, the const last_level also is declared as an int.

After debugging on a label on the screen I notice that if I print on the label (Vars.current_level is int) or (last_level is int) it returns true on the debug version, but on the release version it returns false.

This 3 functions were the problem, they worked fine on the debug version but not on the release:

func current_level_is_the_last():
	return Vars.current_level == last_level

func set_next_level():
		Vars.current_level += 1

func get_current_palette():
	return get_palette(Vars.current_level)

After many tries, specially on the set_next_level() function, this is how they finally worked correctly on the release version.

func current_level_is_the_last():
	return int(Vars.current_level) == int(last_level)

func set_next_level():
		var curr_level:int = Vars.current_level
		var next_level:int = curr_level + 1
		Vars.current_level = next_level

func get_current_palette():
	var curr_level: int = Vars.current_level
	return get_palette(curr_level)

If would be nice to understand better what happened and how to avoid it on the future. Any thoughts would be highly appreciated... Thanks!!

Maybe Vars.current_level cannot be modified directly? That seems to be the only difference that I see right off between the two scripts, is that in the working release script you need to assign it to a variable and then access it. What it could be is that by assigning it to a variable, it makes a copy, you can then modify and use the copy, and then if you need to reassign it just dumps the old value (line 7). I'm not sure why that would be needed though. I know in C# there is several properties that are just getters, you cannot do something like property.value = 10 and instead of have to break it out similarly to what you did to get it working. I didn't think there was any properties that would need that in GDScript though.

Regardless, I'm glad you were able to find a solution. Thanks for sharing it so others can benefit from it if they have a similar issue!