Why is my _ready being called twice?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By BGamers11

I find this very strange as to everything works fine, except when I add a scene in AutoLoad. My _ready is only called twice when I put my TitleScreen scene in AutoLoad, and somehow when I change scene everything goes back to normal.

Why you put TitleScreen in AutoLoad?
If you want it to start at the beginning of the game, you should put it as the main scene, not as an autoload.

p7f | 2020-09-28 20:41

Are you sure you’re not instancing it twice? (Having it autoload and it being on your scene hierarchy, for example)

Lazarwolfe | 2020-09-28 21:20

1-I put it in autoload because after searching a lot in godot forums and other medias, it seens the only way to put a music that doesn’t reset between scenes. Even with my workaround the music doesn’t goes smoothly when switching scenes.

2-I don’t really get what instancing twice means. If you could make a different explanation it would be really helpful, thanks.

BGamers11 | 2020-09-28 22:59

Instancing- It’s a “copy” per say of your scene/script, by autoloading it and having your title screen you have two copies of your script running at the same time, don’t autoload the script, this could have so many errors.

Moldor2 | 2020-09-29 13:03

:bust_in_silhouette: Reply From: Moldor2

To fix your issue there is a few functions you can use with the audio player to resume the music exactly where you want it to.

First, you need to get where your music will stop at when you transition scenes

var music_time = get_position_playback() #returns the amount (in seconds) of where the audiostream is at

You can then use another function to resume the play of the music at a specified position.

$AudioStreamPlayer.play(music_time) # will resume the music at the value of music_time

And I repeat from my earlier comment, don’t autoload the script for your titlescreen, create a new script, autoload that and hold the music_time variable in that script so you could call on it between scenes.
For example: You have a script named Global.gd autoloaded and there is a single statement in the script var music_time, to call on it you would write this statement before you transition scenes:

Global.music_time = get_position_playback()

Then in your other script for the scene you transition to you would write:

if Global.music_time != null: # check to make sure you don't get an error
     $AudioStreamPlayer.play(Global.music_time)
else:
     $AudioStreamPlayer.play() #starts music from beginning

As I already said, that was exactly my workaround. It kinda works, but as I said, it isn’t smoothly. Every time I switch scenes, the delay needed to completely switch them makes the music stutter, or basically stop till the scenes fully loads. It isn’t a very big delay, but it’s extremely annoying, and sounds horrible.

BGamers11 | 2020-09-29 23:17

Would it be sensible to autoload an AudioStreamPlayer script and have music be handled in a more global context? (make it a singleton basically) Or would it be a bad practice?

Lazarwolfe | 2020-09-30 17:03

Thank you very much, Lazarwolfe! Your suggestion worked out perfectly, and it’s kinda funny how it’s so simple yet most people like me didn’t realize it at all. Also thank you Moldor2 for explaining what instancing is.

BGamers11 | 2020-10-01 06:36

Be careful though, I don’t think that autoloading many things is a good practice, it might be a good idea to look into a solid workaround, since the singleton pattern (the fancy name for autoloading) is a bit of an object oriented programming malpractice, as far as I know.

Lazarwolfe | 2020-10-01 23:28

:bust_in_silhouette: Reply From: BGamers11

(Can’t select correct answer but this question has been answered)