Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Splash screen transitions to black screen on Android #74348

Closed
CGcaspar opened this issue Mar 4, 2023 · 40 comments · Fixed by #92965
Closed

Splash screen transitions to black screen on Android #74348

CGcaspar opened this issue Mar 4, 2023 · 40 comments · Fixed by #92965

Comments

@CGcaspar
Copy link

CGcaspar commented Mar 4, 2023

Godot version

4.0

System information

Pixel 5, Adreno 620, Forward Mobile

Issue description

In exported Android projects, the configured splash screen is only visible for a very brief moment. Immediately afterwards, there is a transition to a black screen which, depending on how many resources are loaded in a project, remains until the first frame is rendered.

In larger projects where more resources are loaded, the black screen is visible for around 3 seconds depending on the device.

The same black screen is also visible when you check "Use Gradle Build".

Release vs. Debug build also makes no difference.

godot4-splashscreen-black.mp4

Steps to reproduce

  1. Create new empty project
  2. Create an empty main scene with a Control node
  3. Check "Import ETC2 ASTC" in Project Settings
  4. Configure Export for Android
  5. Export to device

Minimal reproduction project

N/A

@phil-hudson
Copy link
Contributor

hey @CGcaspar - did you find a solution to this? I'm having the same issue

@phil-hudson
Copy link
Contributor

FYI - changing to gl_compatiblity renderer resolved this for me!

@BrianJesusFreakGreen
Copy link

I'm seeing this as well. The amount of loading happening makes no difference. If I make an empty first scene that loads the rest of the game, the first empty scene still is preceded by a black screen that can last 4 or 5 seconds on older devices (especially kids fire tablets). In GL Compatibility the only options are OpenGL3

@Zireael07
Copy link
Contributor

That's because Compatibility equals OpenGL3

@fieldbit
Copy link

fieldbit commented Dec 8, 2023

Any update /workaround? i see black splash screen on Android (works perfectly on Windows), godot 4.0.4, Samsung S20

@mahdisml
Copy link

mahdisml commented Dec 8, 2023

Any update /workaround? i see black splash screen on Android (works perfectly on Windows), godot 4.0.4, Samsung S20

Update to 4.2 Version (#82525)

@juse4pro
Copy link

juse4pro commented Dec 8, 2023

Update to 4.2 Version (#82525)

Unfortunately pushing to 4.2 does not solve the problem.

@ceyhundirilce
Copy link

I'm currently having the same problem. I guess the black screen cannot be changed. Has anyone solved this?
(Godot 4.1.3)

@elektrasta
Copy link

i'm currently having the same problem in godot version 4.1.3, I want knowledgeable friends to come up with a solution, help!!

@ceyhundirilce
Copy link

ceyhundirilce commented Dec 9, 2023

SOLVED! Adsız

@goranovs
Copy link

goranovs commented Feb 1, 2024

This still exists on 4.2.1 switching to compatibility is not an option. It happens even on high end devices as Samsung galaxy ultra s20.

@Zireael07
Copy link
Contributor

@goranovs Compatibility is recommended for actual mobile devices because Vulkan drivers on mobile suck.

@goranovs
Copy link

goranovs commented Feb 3, 2024

I don't see any difference in performance. It's just that black screen that seems to be reported multiple times across all versions of Godot. Including here #62863. Changin to gl_compatiblity does not solve the problem.

@pudlik
Copy link

pudlik commented Feb 10, 2024

Edit: Rendering.mobile = gl_compatibility works actually, thanks!

@goranovs
Copy link

If I set Rendering.mobile = gl_compatibility the only difference is that it does the black screen very quickly after the game icon, but yet no splash image is displayed.

@djrain
Copy link

djrain commented Feb 28, 2024

This issue is really really bad. I'm pretty sure Google rejected our app because it's taking so long on this black screen that they thought it was frozen, or it was just unacceptable (6-7 seconds). Meanwhile it starts up immediately on iOS. Would love to help, but I'm no android dev...

@brcontainer
Copy link

brcontainer commented Feb 28, 2024

@djrain I have 5 mobile projects, created using Godot 4.1 (Forward Mobile), and none of them took 10 seconds (note that my test device has poor performance).

I think the problem you face is because the main scene must be a level of your game that has many resources, it would be interesting for you to add a loading screen for the levels, see the documentation:

See an example:

...

const INITIAL_LEVEL: StringName = "res://levels/first_level.tscn"

var requesting: bool = false

@onready var progressbar: ProgressBar = $ProgressBar

func _ready() -> void:
    var result := ResourceLoader.load_threaded_request(INITIAL_LEVEL)

    if result != OK:
        prints("Error", "ResourceLoader load failed", result)
    else:
        requesting = true

func set_progress(value: float) -> void:
    if progressbar.value < value:
        progressbar.value = value

func _process(_delta) -> void:
    if requesting:
        status = ResourceLoader.load_threaded_get_status(INITIAL_LEVEL, progress)

        match status:
            ResourceLoader.THREAD_LOAD_IN_PROGRESS:
                set_progress(progress[0] * 100.0)

            ResourceLoader.THREAD_LOAD_FAILED:
                requesting = false
                prints("Error", "ResourceLoader load failed", status)

            ResourceLoader.THREAD_LOAD_LOADED:
                requesting = false

                set_progress(100.0)

                var result := tree.change_scene_to_packed(
                    ResourceLoader.load_threaded_get(INITIAL_LEVEL)
                )

                if result != OK:
                    prints("Error", "ResourceLoader load failed", result)

...

I hope this helps.

@djrain
Copy link

djrain commented Feb 28, 2024

@brcontainer thanks for the suggestion! I edited my comment to say 6-7 seconds, it was only taking 10 seconds on the debug build straight from Godot. I guess it's faster on a release build. But 7 seconds is still unacceptable. And our game already loads resources on our custom splash scene, so loading is not the issue, unfortunately.

@brcontainer
Copy link

brcontainer commented Feb 29, 2024

@djrain I have 5 games (prototypes) for mobile, none of my games take more than 0.5 seconds after the splascreen. The black screen appears, but only for 0.5 seconds, my main scene in all games are custom load screens with a progress bar, using code similar to what I showed you above, so the game itself, with all the features, is just presented later. Every game I see, even light ones, has a loading screen, even PC games.

Adding a load screen is a matter of user experience, as if it doesn't have this the user may think that the game has frozen. Another thing that might be interesting to add is the screen transition between scenes.

@BachDovn
Copy link

BachDovn commented Apr 11, 2024

hey @CGcaspar - did you find a solution to this? I'm having the same issue on godot 4.2.1 and other higher version doesnt solve

@brcontainer
Copy link

brcontainer commented Apr 11, 2024

@BachDovn It's not something that can be resolved in the settings or via script, it's a bug that needs to be fixed in the Godot core. As long as the issue is open it is unlikely that the problem will be fixed. I recommend that you follow what I said in the previous comment:

I have 5 games (prototypes) for mobile, none of my games take more than 0.5 seconds after the splascreen. The black screen appears, but only for 0.5 seconds, my main scene in all games are custom load screens with a progress bar, using code similar to what I showed you above, so the game itself, with all the features, is just presented later. Every game I see, even light ones, has a loading screen, even PC games.

Adding a load screen is a matter of user experience, as if it doesn't have this the user may think that the game has frozen. Another thing that might be interesting to add is the screen transition between scenes.

Create a simple scene, this scene should be the main one, then add a load for the larger scene, using ResourceLoader.load_threaded_request(scene), script example:

extends Control

const SAMPLE_SCENE := "res://3d_sample.tscn"

var progress: Array[float] = []
var loading: bool = false
var status: ResourceLoader.ThreadLoadStatus

@onready var tree: SceneTree = get_tree()
@onready var progressbar: ProgressBar = $VBoxContainer/ProgressBar

func _ready():
	ResourceLoader.load_threaded_request(SAMPLE_SCENE) # initiate loading scene
	loading = true

func _process(_delta) -> void:
	if loading:
		status = ResourceLoader.load_threaded_get_status(SAMPLE_SCENE, progress)

		match status:
			ResourceLoader.THREAD_LOAD_IN_PROGRESS:
				progressbar.value = progress[0] * 100.0

			ResourceLoader.THREAD_LOAD_FAILED, ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
				loading = false

			ResourceLoader.THREAD_LOAD_LOADED:
				loading = false
				progressbar.value = 100.0
				tree.change_scene_to_packed(ResourceLoader.load_threaded_get(SAMPLE_SCENE))

A scene sample, intro.tscn:

[gd_scene load_steps=2 format=3 uid="uid://cn1t7w3x5k6pk"]

[sub_resource type="GDScript" id="GDScript_2s2fu"]
script/source = "extends Control

const SAMPLE_SCENE := \"res://3d_sample.tscn\"

var progress: Array[float] = []
var loading: bool = false
var status: ResourceLoader.ThreadLoadStatus

@onready var tree: SceneTree = get_tree()
@onready var progressbar: ProgressBar = $VBoxContainer/ProgressBar

func _ready():
	ResourceLoader.load_threaded_request(SAMPLE_SCENE) # initiate loading scene
	loading = true

func _process(_delta) -> void:
	if loading:
		status = ResourceLoader.load_threaded_get_status(SAMPLE_SCENE, progress)

		match status:
			ResourceLoader.THREAD_LOAD_IN_PROGRESS:
				progressbar.value = progress[0] * 100.0

			ResourceLoader.THREAD_LOAD_FAILED, ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
				loading = false

			ResourceLoader.THREAD_LOAD_LOADED:
				loading = false
				progressbar.value = 100.0
				tree.change_scene_to_packed(ResourceLoader.load_threaded_get(SAMPLE_SCENE))
"

[node name="Intro" type="MarginContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/margin_left = 15
theme_override_constants/margin_top = 15
theme_override_constants/margin_right = 15
theme_override_constants/margin_bottom = 15
script = SubResource("GDScript_2s2fu")

[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
size_flags_vertical = 4

[node name="ProgressBar" type="ProgressBar" parent="VBoxContainer"]
layout_mode = 2

@BachDovn
Copy link

@brcontainer I understand your code, you mean make a loading screen, and when load sence done, can change to that sence.
I already use for my project, it working perfect on window but, on android still same. on android mobile it show full progress bar when it done 100% and yes change to that sence but still black screen dont see any 3d sence, but 2d is show.

@brcontainer
Copy link

@BachDovn But it's the black screen on Android that I'm talking about, as I mentioned in the penultimate comment and I still say, read it, if the main scene is small, it will take a maximum of 0.5 seconds, which is acceptable, even if perceptive. But if the main scene is large, the black screen will be even more noticeable, so a loading screen is better.

And I reiterate what I said in the penultimate comment, all my projects are mobile, mainly Android, and I test on slow and old devices, all my projects use a small and intermediate load scene, so this 0.5s (half a second) of the screen black is the result I got on all devices. This time is perfectly acceptable.

And just for better understanding, the main reason I commented is that this bug has not yet been resolved, when the issue is, it will be marked as "closed". Subscribe to this issue and you will be notified.

Thank you for understanding.

@BachDovn
Copy link

@brcontainer are you sure that solve for 3d? because I only have proplem with 3d sence. if your code work for 3d sence that would be nice. I want to learn deeper, and thank you so much for that.

@brcontainer
Copy link

brcontainer commented Apr 11, 2024

@BachDovn All my projects are 3D and in all of them I follow what I suggested, creating a simple scene that is just of type Control:

image

And Control scene will call the 3D scene using ResourceLoader.load_threaded_request(...) + ResourceLoader.load_threaded_get_status(..., progress).

Note: There was an error in the code I suggested in the comment: #74348 (comment), I already corrected it.

@BachDovn
Copy link

@brcontainer I do try, but no progress. Out put show that it run 3d sence, but screen doesnt, it stop at loading screen. My phone running android 11, so I dont think it weak. I think Godot didnt support 3d on mobile. I am disappointed. Maybe it is time to learn and try other engine. Thank you

@brcontainer
Copy link

@BachDovn From what you explained, it seems to me that the problem is something else, unrelated to the current bug reported. The problem should only occur after the splashscreen, if the problem is occurring in other situations it could be a fault in something you did.

@djrain
Copy link

djrain commented Apr 11, 2024

@brcontainer I'd be curious to know how your projects run in 4.2, since in this issue #85264 they say that the splash time became longer in 4.2

@brcontainer
Copy link

brcontainer commented Apr 11, 2024

@djrain @BachDovn

I actually use 4.1, but I tweaked a project for 4.2 and made a video for you to see. Details about the video:

  1. My device is poor
  2. The video recorder degrades the overall performance of the device.
  3. All my projects are 3D
video4954005919919769874.mp4

Black screen took 0.8s to load the intro.tscn scene

@djrain
Copy link

djrain commented Apr 11, 2024

That's encouraging to see, thanks :) Still struggling to get the time down in our game - main scene is a tiny one, and got rid of almost all preloaded resources, but still almost 4 seconds on black screen. I guess the problem must be in autoloads or class_name scripts...

@BachDovn
Copy link

@brcontainer wow...what good news. If you don't mind, can you tell me about your godot settings, which jdk do you use? Do you run it on USB remote debugging or do you export it and install it? How do you set up export? Do you have a YouTube tutorial channel?
I use Godot 4.2.1, template 4.2.1 stable, gradle 7.4.2, jdk17 provided by https://docs.godotengine.org/.
Mobile: Oppo a54, Android 11, 4G ram

@BachDovn
Copy link

BachDovn commented Apr 12, 2024

@brcontainer help me bro,do I setting correct.
main sence 2d:
image.
main script( not auto load):

image

simple sence 3d:
image
setting export:

Export with debug: yes
name="Android"
platform="Android"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../../Godot Export/Test.apk"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false

[preset.0.options]

custom_template/debug=""
custom_template/release=""
gradle_build/use_gradle_build=true
gradle_build/export_format=0
gradle_build/min_sdk="24"
gradle_build/target_sdk="30"
architectures/armeabi-v7a=false
architectures/arm64-v8a=true
architectures/x86=false
architectures/x86_64=false
version/code=1
version/name=""
package/unique_name="com.example.$genname"
package/name=""
package/signed=true
package/app_category=2
package/retain_data_on_uninstall=false
package/exclude_from_recents=false
package/show_in_android_tv=false
package/show_in_app_library=true
package/show_as_launcher_app=false
launcher_icons/main_192x192=""
launcher_icons/adaptive_foreground_432x432=""
launcher_icons/adaptive_background_432x432=""
graphics/opengl_debug=true
xr_features/xr_mode=0
screen/immersive_mode=true
screen/support_small=true
screen/support_normal=true
screen/support_large=true
screen/support_xlarge=true
user_data_backup/allow=true
command_line/extra_args=""
apk_expansion/enable=false
apk_expansion/SALT=""
apk_expansion/public_key=""
permissions/custom_permissions=PackedStringArray()
permissions/access_checkin_properties=false
permissions/access_coarse_location=false
permissions/access_fine_location=false
permissions/access_location_extra_commands=false
permissions/access_mock_location=false
just false for all permissions.

@brcontainer
Copy link

brcontainer commented Apr 12, 2024

@djrain @BachDovn

I created a simple sample, made some adjustments to "project.godot" to optimize on mobile devices. Take the test to confirm if the black screen takes more than 1sec on your devices:

@BachDovn
Copy link

@brcontainer yes, 2 file apk run in my mobile android is stop at 0% progress bar, and just stay that forever

@brcontainer
Copy link

brcontainer commented Apr 12, 2024

@BachDovn It (top at 0% progress bar) seems to be the problem I mentioned, 4.2 has problems with different devices, that's why I'm still on 4.1, until 4.3 is ready.

Anyway, here's a test I did on my device with sample-release.apk:

android-sample.mp4

@BachDovn
Copy link

@brcontainer so, i just try Godot 3.5.3 and change to gles2 and enable import etc.....that solve.

@ivanreyne
Copy link

Same happening to me.

I am using Godot 4.2.2 and when deploying to Android the boot splash screen config gets ignored and whilst loading the first scene it shows a black screen (not even picking up the boot splash custom background colour).

I already tried to have as initial scene a very simple one just to make sure it was not a problem loading resources or something like that but made no difference.

The other thing I realised is that it depends a lot on the device. I have a Motorola G9 phone where it happens but you can barely notice, but on a Samsung Galaxy Tablet it lasts about 5-6 seconds. As I am trying to publish the game I have tried to local install through usb cable as well as downloading the app through the play store for internal testing and the results are the same.

When uploading the app to the Samsung Galaxy Tablet with the usb debug cable I noticed the following output messages:

Exporting Poing AdMob '.cfg' file
0 param: --remote-debug
1 param: tcp://localhost:6007
2 param: --xr_mode_regular
3 param: --use_immersive
Installing to device (please wait...): Samsung SM-T220
--- Device API >= 21; debugging over USB ---
--- DEVICE API >= 21; DEBUGGING OVER USB ---
Reverse result: 0
Godot Engine v4.2.2.stable.official.15073afe3 - https://godotengine.org
Vulkan API 1.1.131 - Forward Mobile - Using Vulkan Device #0: ImgTec - PowerVR Rogue GE8320

and the 5-6 seconds delay happens between
"Reverse result: 0"
and
"Godot Engine v4.2.2.stable.official.15073afe3 - https://godotengine.org"
and then the first scene loaded without any sign of the boot splash screen.

I am using a custom gradle build as I intend to use AdMob. But even without the plugin the problem is the same.

On a side note I had it first with the compatibility render and it also showed the same problem (maybe it took a bit less time to load). But I cannot go back to the compatibility render because it gives me now an error on a skeleton shader compilation. Obviously this is a different issue.

I hope this additional info helps.

@ivanreyne
Copy link

Hi, a bit more information about this problem.

It seems that from Android 12 the splash screen config/rules have changed. Moreover the "new" Android splash screens can only contain a icon image (that can be animated) on the center plus a background colour. This is what the users will see since they start loading the app until the very first scene is loaded by the Godot engine. It is possible that this is a bit of a breaking change compared to what was allowed to do until now.

This is the relevant link to the Android documentation:
https://developer.android.com/develop/ui/views/launch/splash-screen
And they also provide info on how to migrate to the new system:
https://developer.android.com/develop/ui/views/launch/splash-screen/migrate

There is this repository that shows you how to configure the entire thing. All the "res" files, changes on the AndroidManifest.xml, etc. I think it is based on Godot 3.x but the changes on the Android files are the same. The only thing that changes is the way it loads the "game scene" after the Android splash screen closes.

In my case (I already had a custom graddle build) I ended up using the splash screen configuration very similar to what is described in that repository and then I followed some other comments to have a very simple "initial main scene" that shows the actual "nice splash scene" and that is the responsible for loading the "game main scene" on the background. And then on that "nice splash scene", as it is a proper Godot scene, you can have anything (any animations, progress loaders, etc) you want.

Hope it helps and gives and overview of the problem to the maintainer of the default graddle build template.

@Alex2782
Copy link
Contributor

Alex2782 commented May 9, 2024

Does it make sense to display the "desktop"-version splash screen again on Android?

implementation "androidx.core:core-splashscreen:1.0.0" This also increases the APK size.

godot/main/main.cpp

Lines 2848 to 2849 in cff016d

#if !defined(TOOLS_ENABLED) && (defined(WEB_ENABLED) || defined(ANDROID_ENABLED))
bool show_logo = false;

The configuration Minimum Display Time should also not be used on Android, this extends the black screen.


show_logo = true works identically (like on desktop) in the master branch, but the black screen is still briefly visible on Android. Could be Vulkan initialization process.

Bildschirmfoto 2024-05-09 um 02 08 05

@unforgiven1990
Copy link

unforgiven1990 commented Aug 7, 2024

@brcontainer I understand your code, you mean make a loading screen, and when load sence done, can change to that sence. I already use for my project, it working perfect on window but, on android still same. on android mobile it show full progress bar when it done 100% and yes change to that sence but still black screen dont see any 3d sence, but 2d is show.

This is exactly my issue too! So frustrating

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.