@@ -39,8 +39,8 @@ export class SceneAction<T extends typeof SceneActionTypes[keyof typeof SceneAct
3939 . flush ( ) ;
4040 scene . local . init ( state . getStorable ( ) ) ;
4141
42- state . getExposedStateAsync < ExposedStateType . scene > ( scene , ( exposed ) => {
43- SceneAction . initBackgroundMusic ( scene , exposed ) ;
42+ state . getExposedStateAsync < ExposedStateType . scene > ( scene , async ( exposed ) => {
43+ await SceneAction . initBackgroundMusic ( scene , exposed ) ;
4444 awaitable . resolve ( next ) ;
4545
4646 state . logger . debug ( "Scene Action" , "Scene init" ) ;
@@ -49,10 +49,19 @@ export class SceneAction<T extends typeof SceneActionTypes[keyof typeof SceneAct
4949 return awaitable ;
5050 }
5151
52- static initBackgroundMusic ( scene : Scene , exposed : ExposedState [ ExposedStateType . scene ] ) {
53- if ( scene . state . backgroundMusic ) {
54- exposed . setBackgroundMusic ( scene . state . backgroundMusic , scene . config . backgroundMusicFade ) ;
52+ /**
53+ * Initialize background music for the target scene.
54+ * Waits until the previous BGM has completely faded out (if any) before
55+ * resolving, ensuring seamless audio transition when jumping between scenes.
56+ */
57+ static async initBackgroundMusic ( scene : Scene , exposed : ExposedState [ ExposedStateType . scene ] ) : Promise < void > {
58+ if ( ! scene . state . backgroundMusic ) {
59+ return ;
5560 }
61+ // `setBackgroundMusic` already handles fade-out of the previous track and
62+ // fade-in of the new track. We simply await it so that the caller can
63+ // chain subsequent actions after the transition finishes.
64+ await exposed . setBackgroundMusic ( scene . state . backgroundMusic , scene . config . backgroundMusicFade ) ;
5665 }
5766
5867 static createSceneSnapshot ( scene : Scene , state : GameState ) : SceneSnapshot {
0 commit comments