godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.58k stars 21.27k forks source link

If save file when autoloaded script exited node tree(quit ), will sometimes drop the file on Android #83969

Open SmallKi opened 1 year ago

SmallKi commented 1 year ago

Godot version

4.1.2

System information

Windows11, GLES3

Issue description

My game running in android.

And I have a autoload script, witch will save the data(write some data to a file, and call file.close() when ended) when exit the node tree (in _exit_tree function) But In some phone, the data always rollback when they foce quit the game or killed by system in background.
First I think that maybe the game quit before the file totally write in so the file was broken. So I use two file to save, one as data backup. The two files will save together, so I think it will remain one at least. But the very confusing thing is the two files are all droped or broken maybe!!!!! I have no idea about it, and it happens frequently in some phones, but some others never encounter this.

Steps to reproduce

In the project below, I rewrite some save func based by Resource class. And I save data in the _exit_tree function. Exported it to android, If you try to force quit the game or make it killed in the background in some phones, you will sometimes got an unsaved data file(which is rollback).

Now I have removed the logic in the _exit_tree function, but I think here maybe do exist some problems.
Thanks.

Minimal reproduction project

FileSaveProject (1).zip

### Tasks
Calinou commented 1 year ago

Please upload a minimal reproduction project[^1] to make this easier to troubleshoot.

[^1]: A small Godot project which reproduces the issue, with no unnecessary files included. Be sure to not include the .godot folder in the archive (but keep project.godot).

Drag and drop a ZIP archive to upload it. Do not select another field until the project is done uploading.

Note for C# users: If your issue is not Mono-specific, please upload a minimal reproduction project written in GDScript or VisualScript. This will make it easier for contributors to reproduce the issue locally as not everyone has a Mono setup available.

Force-quitting, being background-killed or crashing will not ensure that _exit_tree() is called (it is only guaranteed to be called when the engine exits via get_tree().quit()). You'd need a signal handler to be able to do that, which Godot currently doesn't expose yet.

SmallKi commented 1 year ago

I have uploaded a minimual project, hope it can be helpful.

Alex2782 commented 1 year ago
func _exit_tree() -> void:
    print("_exit_tree");
    save_player()

_exit_tree is unsuitable I think, tested via Android Studio "app/assets" folder and on MacOS Godot 4.2 Beta5. I could not see the log output "_exit_tree".


Possible solutions

func _notification(what):
    print ("_notification:", what);
    #save_player()

On Android, I would recommend Pause and Resume. If the app stays in the background for a long time, then Android system might release the resources and when a user activates the app, then the app will probably restart. (or crash)


image

I have added a CrashReporter / Thread.UncaughtExceptionHandler and SIGNAL-Listener to my custom build to check whether the error messages can be displayed. I discussed this with 'm4gr3d' in the Android chat. This extension would have little chance. Maybe I'll create a plugin at some point.

image