[RealityKit] Cannot OpenImmersiveView

I was developing my project just like HappyBeam, having a mechanism that after playing a small game round, a main menu pops up letting player to play again or back to main menu.

When I start my first game after installing it on my vision pro, it works fine, which was basically like HappyBeam, counting from 3 to 1 then await openImmersiveView(id: "***") to entering my game. After finish the round, I call await dismissImmersiveView() and reset my game ready for the next move. Letting player to choose play again or back to menu to continue my game.

However, this time, when my counter counting 3 to 1, the immersive view didn't show up and the visionOS menu showed up instead (I guess it's because immersive view cannot be open). Some error showed in my logger are below

<FBSWorkspaceScenesClient:0x281820e00 com.apple.frontboard.systemappservices> scene request failed to return scene with error response : <NSError: 0x2839bc270; domain: FBSWorkspaceErrorDomain; code: 1 ("InvalidScene"); "scene invalidated before create completion">
------------------------------------------------
Unable to present an Immersive Space for id 'ImmersiveSpace': Error Domain=FBSWorkspaceErrorDomain Code=1 "scene invalidated before create completion" UserInfo={BSErrorCodeDescription=InvalidScene, NSLocalizedFailureReason=scene invalidated before create completion}
------------------------------------------------
Error: BSLogAddStateCaptureBlockWithTitle(EventDeferringState:com.milanow.mygame:SFBSystemService-C90B0828-4522-4098-9E6A-0D5968CFCEB8) state data format error: <NSError: 0x283947360; domain: BSSharedStateCapturing; code: 1; "Input generated no data"> {
    NSUnderlyingError = <__NSCFError: 0x2839451d0; domain: NSCocoaErrorDomain; code: 3851> {
        NSDebugDescription = Property list invalid for format: 200 (property lists cannot contain NULL);
    };
}

Wonder what happens here since no helpful info could be found online.

(I think the openimmersiveview code snippet is boring but I may still post it here)

var body: some Scene {
        Group {
            WindowGroup(id: "MainUI") {
                MainView()
            }
            .windowStyle(.plain)
            .windowResizability(.contentSize)

            ImmersiveSpace(id: "ImmersiveSpace") {
                GameView()
            }
            .immersionStyle(selection: .constant(.mixed), in: .mixed)
        }
.onChange(of: gameModel.state) { oldValue, newValue in
            guard oldValue != newValue else {
                return
            }
            
            if case let .dismissingImmersiveSpace(finish) = newValue {
                Task {
                    await dismissImmersiveSpace()
                    openWindow(id: "MainUI")
                    finish()
                }
            } else if case let .openingImmersiveSpace(startPlaying) = newValue {
                Task {
                    await openImmersiveSpace(id: "ImmersiveSpace")
                    dismissWindow(id: "MainUI")
                    startPlaying()
                }
            } else if case .playing = oldValue {
                openWindow(id: "MainUI")
            } else if case .playing = newValue {
                dismissWindow(id: "MainUI")
            }
        }
}

You can see that nothing magic here just follow what HappyBeam says. (Wonder what makes a scene invalid really)

Replies

Hello @milanowth,

I realize you mentioned this is similar to Happy Beam, but could you provide a focused sample project that reproduces the issue? I can investigate the issue more effectively in a focused sample project.