godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.13k stars 92 forks source link

Implement background services on mobile (Android/iOS) #3347

Open nathanfranke opened 3 years ago

nathanfranke commented 3 years ago

Edit: Looking back at this, not sure if letting a node process in the background would be a good idea. 1) Polling every frame may take a lot of battery. 2) There might be some overhead with this, e.g. would you need the SceneTree to be "active" during this time?

Maybe we should look at how other game engines handle it. Use cases include:


Describe the project you are working on

Audio player app that needs background playback support

Describe the problem or limitation you are having in your project

When I turn off my screen or tab out, all app functionality ceases.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Proposal version of godotengine/godot#36583

Add some way to process a selection of nodes always, even when the app is running in the background.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Add another pause mode option to support background processing.

image

If this enhancement will not be used often, can it be worked around with a few lines of script?

Definitely not with GDScript. it might be possible with a custom build module but that probably still couldn't let special nodes process such as AudioStreamPlayers.

Is there a reason why this should be core and not an add-on in the asset library?

I don't think add-ons can make a node process from a service thread. Even then, that would be hacky.

Calinou commented 3 years ago

Adding a new pause mode for this doesn't feel like a very local solution to me :slightly_smiling_face:

nathanfranke commented 3 years ago

Adding a new pause mode for this doesn't feel like a very local solution to me slightly_smiling_face

I was mostly thinking that this could be implemented on other platforms, though not sure which ones

kisg commented 3 years ago

This is a interesting proposal, could you please make it more generic to support iOS as well? I was planning to add this support myself as well both for Android and iOS. For the design, I think it makes sense to look at how iOS handles background modes for apps, because it is more constrained compared to Android: https://developer.apple.com/documentation/bundleresources/information_property_list/uibackgroundmodes/ https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/creating_a_basic_video_player_ios_and_tvos/enabling_background_audio https://developer.apple.com/documentation/backgroundtasks

nathanfranke commented 3 years ago

This is a interesting proposal, could you please make it more generic to support iOS as well? I was planning to add this support myself as well both for Android and iOS. For the design, I think it makes sense to look at how iOS handles background modes for apps, because it is more constrained compared to Android: https://developer.apple.com/documentation/bundleresources/information_property_list/uibackgroundmodes/ https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/creating_a_basic_video_player_ios_and_tvos/enabling_background_audio https://developer.apple.com/documentation/backgroundtasks

The post text is already pretty platform agnostic, but I updated the title. I didn't even know iOS had these since I know battery optimizations are way more strict.

For implementation, I still like the pause mode idea, but it could also be done with another node type (maybe with all of its children running in background). The main requirement for my personal reasons is the ability to have a node process in the background (AudioStreamPlayer).

Here's another idea for implementation: make an export flag that says "run the entire app as a service". Then it will be up to the implementation to hook into the window focus events and do energy saving manually (i.e pause the scene tree)

kisg commented 3 years ago

The post text is already pretty platform agnostic, but I updated the title. I didn't even know iOS had these since I know battery optimizations are way more strict.

Thank you.

For implementation, I still like the pause mode idea, but it could also be done with another node type (maybe with all of its children running in background). The main requirement for my personal reasons is the ability to have a node process in the background (AudioStreamPlayer).

I think the pause mode is a good start, but I have to check out exactly what it means and how it could be hooked into the iOS APIs. My use case is also running the AudioStreamPlayer in the background, so we have the same goal here.

Here's another idea for implementation: make an export flag that says "run the entire app as a service". Then it will be up to the implementation to hook into the window focus events and do energy saving manually (i.e pause the scene tree)

Interesting idea, I am not sure how difficult would it be to use it.

nathanfranke commented 3 years ago

My use case is also running the AudioStreamPlayer in the background, so we have the same goal here.

:tada:

Interesting idea, I am not sure how difficult would it be to use it.

I'm mostly curious about stuff like rendering, not sure if that needs to be done in some main thread.

kisg commented 3 years ago

My use case is also running the AudioStreamPlayer in the background, so we have the same goal here.

tada

Interesting idea, I am not sure how difficult would it be to use it.

I'm mostly curious about stuff like rendering, not sure if that needs to be done in some main thread.

AFAIR on iOS, while the app is in background, only specific entry points are called (e.g. the audio playback callback if we are in audio playback mode), the main thread is stopped, so rendering is not possible at all. Also the number of CPU cycles is very limited, so we should take care to only run the nodes / objects that are absolutely necessary.

One idea I am toying with is that there could be a BackgroundServer singleton, and components that need some part to run in the background could register with it, e.g. by connecting to one of its signals. In background mode the normal main thread would not run (everything would be paused), only this BackgroundServer would emit the signals to the registered objects. This way we could ensure minimal energy / cpu usage in the background. What do you think?

nathanfranke commented 3 years ago

@kisg BackgroundServer sounds very localized, which is great. I am curious how easy it will be to implement with something like AudioStreamPlayer (Which uses its own thread)

agrimminck commented 1 year ago

Any updates on this proposal? I'm doing a social game for mobile and the fact that minimizing the game disconnects the client is a huge deal. It would be wonderful to let the game run in the background

Calinou commented 1 year ago

Any updates on this proposal? I'm doing a social game for mobile and the fact that minimizing the game disconnects the server is a huge deal. It would be wonderful to let the game run in the background

To my knowledge, nobody has started implementing this feature yet.

However, note that it's probably better to design your game to work well with regular disconnection/reconnection. This is because mobile OSes aggressively kill background apps to save on battery, no matter what kind of permissions your app requests. Some Android ROMs will do this more than others, and you can't predict how it'll behave.

bappitybup commented 3 months ago

bumping this. I'm making an app that can mix sounds together to form new melodies and would like to be able to listen to it while using other apps or with my phone screen locked like how spotify/soundcloud/youtube works

KanuniiAhmed commented 2 months ago

+1 for this very interesting