issue with return to game post Azure mobile services for Authentication

Topics: Windows Phone 8
Feb 21, 2014 at 8:26 PM
Anyone using Azure Mobile Services for a WP8-based Cocos2d-XNA game?

I've had all sorts of issues in getting back to my game once the user logs in via any of the supported authentication methods provided by Azure.

I am able to use the Dispatcher (InvokeAsync) from my GamePage to run the Azure client's LoginAsync method on the UI thread, which does pop up the UI controls on WP8 to enter login details. But as soon as I submit and get a valid ID back from the auth provider I can't seem to get back to the running Cocos2d game. Well, that's not entirely true - the game loop continues to run and I can even push new scenes in via the CCDirector, but nothing is drawing on the screen. I'm just getting a black screen with the little red loading dashes that you see when the native UI is doing something.

I also tried setting some shared state variables when the login is successful and then checking for this condition in the Update loop for both AppDelegate (derived from CCApplication) as well as for Game1 (derived from the XNA game). I would then use the CCDirector to either resume a scene or replaceScene with a new one. None of these approaches are working.

No obvious exceptions either...

Do I need to do something special to get back to my game? I tried pausing and resuming it via CCDirector without any luck, and when I trace into the Cocos2d-XNA source I see that it's resetting the graphics device...which is probably why I'm not seeing anything, but why would it need to reset the graphics device?

I see it calling ReInit on the Texture2D objects...just not sure why.

Thanks!
Coordinator
Feb 24, 2014 at 1:33 AM
Make sure you are using the source version of cocos2d-xna. I found that Windows 8.1 on Nokia 928 had some issues with the restart of the game after going to a new xaml page. You can see this in Santa Shooter which works on windows 8 with a nokia 820, but not on 8.1 with a 928. I fixed the source version of cocos2d-xna and verified that the fb integration works in Santa Shooter. The fb integration uses the same kind of xaml-page authentication that you are doing with Azure.
Feb 27, 2014 at 12:41 AM
I'm using the latest (as of today) from the master branch of Cocos2d-XNA, including the develop branch of the forked MonoGame for Cocos2d-XNA.
I see some recent commits here but nothing that seems to be related to restart of the game or re-init of the graphics device. Do you have any more information on what you fixed in the source version of cocos2d-xna for your FB authentication to work?

I'm running this on WP8 on a Nokia 520 (but it also has the same behavior in the emulator).

My game code running in the Cocos scene that I want to trigger the authentication, is making a call out to a method I defined in my GamePage.xaml.cs.
That GamePage method is doing something like the following:
        Dispatcher.InvokeAsync(async () =>
        {
             ....
               //use Azure mobile service client to make call to authenticate with Identity Provider
               //store the retrieved userId in current game's data
             ....
        }
The code executes and retrieves a userID just fine, but when this GamePage method returns it looks like it's just trying to reinitialize the graphics context and getting stuck. The display never changes back to my game scene.

Here's the call stack - it looks like the CCDrawManager is determining that it needs to reinit all resources based on the value of m_bNeedReinitResources:
cocos2d-xna.DLL!Cocos2D.CCTexture2D.Reinit() Line 755   C#
cocos2d-xna.DLL!Cocos2D.CCGraphicsResource.ReinitAllResources() Line 1721 C#
cocos2d-xna.DLL!Cocos2D.CCDrawManager.BeginDraw() Line 595  C#
cocos2d-xna.DLL!Cocos2D.CCApplication.Draw(Microsoft.Xna.Framework.GameTime gameTime) Line 213  C#
MonoGame.Framework.DLL!Microsoft.Xna.Framework.Game..cctor.AnonymousMethod__18(Microsoft.Xna.Framework.IDrawable drawable, Microsoft.Xna.Framework.GameTime gameTime) Line 624  C#
MonoGame.Framework.DLL!Microsoft.Xna.Framework.Game.SortingFilteringCollection<Microsoft.Xna.Framework.IDrawable>.ForEachFilteredItem<Microsoft.Xna.Framework.GameTime>(System.Action<Microsoft.Xna.Framework.IDrawable,Microsoft.Xna.Framework.GameTime> action, Microsoft.Xna.Framework.GameTime userData) Line 920   C#
MonoGame.Framework.DLL!Microsoft.Xna.Framework.Game.Draw(Microsoft.Xna.Framework.GameTime gameTime) Line 629    C#
MonoGame.Framework.DLL!Microsoft.Xna.Framework.Game.DoDraw(Microsoft.Xna.Framework.GameTime gameTime) Line 733  C#
MonoGame.Framework.DLL!Microsoft.Xna.Framework.Game.Tick() Line 576 C#
MonoGame.Framework.DLL!MonoGame.Framework.WindowsPhone.SurfaceUpdateHandler.Draw(SharpDX.Direct3D11.Device device, SharpDX.Direct3D11.DeviceContext context, SharpDX.Direct3D11.RenderTargetView renderTargetView) Line 69  C#
MonoGame.Framework.DLL!MonoGame.Framework.WindowsPhone.XamlGame<PetFortune.Game1>.DrawingSurfaceBackgroundContentProvider.Draw(SharpDX.Direct3D11.Device device, SharpDX.Direct3D11.DeviceContext context, SharpDX.Direct3D11.RenderTargetView renderTargetView) Line 86    C#


Thanks again for your help.
Jason
Coordinator
Feb 27, 2014 at 5:52 AM
Your problem sounds vaguely familiar. What I did with SS and FB was to use the navigator.Back() when the authentication was completed.

here is what the authentication success callback looks like for our FB integration:
    private void LoginSucceeded(string accessToken)
    {
        FacebookHelper.AccessToken = accessToken;
        SantaShooterGameState.FacebookAuthToken = accessToken;

        var fb = new FacebookClient(accessToken);

        fb.GetCompleted += (o, e) =>
        {
            if (e.Error != null)
            {
                Dispatcher.BeginInvoke(() => MessageBox.Show(e.Error.Message));
                return;
            }

            var result = (IDictionary<string, object>)e.GetResultData();
            var id = (string)result["id"];
            FacebookHelper.UserId = id;
            SantaShooterGameState.FacebookLogin = id;

            Dispatcher.BeginInvoke(() =>
            {
                if (NavigationService.CanGoBack)
                {
                    NavigationService.GoBack();
                }
                else
                {
                    var url = string.Format("/GamePage.xaml?access_token={0}&id={1}", accessToken, id);
                    Dispatcher.BeginInvoke(() => NavigationService.Navigate(new Uri(url, UriKind.Relative)));
                }
            });
        };

        fb.GetTaskAsync("me?fields=id");
    }
Feb 27, 2014 at 5:37 PM
Thanks - I guess you have your game navigate to a separate XAML page first, before they sign-in?

I was trying to get my Cocos2D scene to call directly into my authentication logic in GamePage.xaml (the main game page) and then to simply re-direct to another Cocos2D scene.

I just tried using NavigationService.GoBack() and I get the same errors. In fact, I tried creating a separate page (Auth.xaml) and while I can navigate from my Game to that XAML page, as soon as I hit the back button to go back to the game in progress (which should be GamePage.xaml) I get the re-init of the graphics device / textures:
reinit called on texture '' 256x32
reinit called on texture '' 286x116
reinit called on texture '' 180x116
reinit called on texture '' 435x116
reinit called on texture '' 696x116
reinit called on texture '' 878x116
reinit called on texture '' 270x116
reinit called on texture '' 600x900
reinit called on texture '' 2048x2048

I wonder if this has anything to do with me also using CCBI scene files?
Coordinator
Feb 27, 2014 at 5:52 PM
Send me an email with your GitHub name and I will show you how we do it in santa shooter.