World Enduro Rally

I'm happy to share the result of the work I've been doing in the last months: yesterday, World Enduro Rally came to light.



The game is available for XBoxOne, Steam, Android and Windows. You can get all the details at its Facebook page, or download directly here:





Hope you like it!

Como mejorar tu protección contra ciberataques como WannaCry, en 3 sencillos pasos


Nota: Consejos genéricos para Windows 8 y 10. Podría no aplicar a versiones anteriores de Windows. Esto es solo un consejo que ayuda a mejorar la seguridad, y no garantiza ningún tipo de invulnerabilidad a éste u otro tipo de ataques. El autor de este blog no es experto en seguridad y no ofrece ninguna garantía en absoluto. Use it at your own risk. 

Manually copying Unity's APK and OBB files to an Android device for testing

When developing an Android game that is meant to be published through the PlayStore, there's a limitation regarding the maximum file size of the APK. It currently can't exceed 100 MB.

The thing is that games usually go beyond that limit. To deal with that, Google offers the so called APK Expansion Files. Every application can include up to 2 of them, with a maximum size of 2 GB each.

If your game goes beyond 100 MB, you can easily instruct Unity to split the game in two by checking the "Split Application Binary" in Edit->Project Settings->Player->Android->Publishing Settings.

Image result for unity split application binary

That will generate two files instead of one:
  • APK: the usual APK file with all the binaries, scripts etc, and the first scene included in the build settings (the scene with build index 0). You need to take care that the first scene is small enough so this APK doesn't go beyond 100 MB. In general, this scene is usually just a loading icon, or a game logo that is displayed while loading. 
  • OBB: A second Expansion File with the OBB, holding everything else. 
Some time ago, it was necessary to use a Unity plugin to deal with OBB loading, but this is no longer necessary. So, first of all, DO NOT USE that plugin. In fact, it hasn't been updated for years, and won't work in current versions of Unity. 

Current versions of Google PlayStore natively support the distribution of OBB files, so you won't need to do anything special besides providing the OBBs along with the APK when you upload your game.

Note: usually, the first time you upload your game to Google Play, it won't ask you for OBB expansion files (I guess that's a bug in the system). If that's your case, simply generate a second version of your game, and re-upload your APK. Then it will ask for Expansion Files properly. 

How to install the game locally, in a test device? 

In normal circumstances, you  just create one big APK, copy it manually to the SD-Card of your phone, and install the game by tapping on the APK file. If you do that now, the game will install fine but it won't be able to find the Expansion OBB files, so the first scene will load fine, but it will probably get stuck there. 

In order to let the game find the OBB files, you need to:

1.- Rename the OBB so it follows the convention:

Unity creates valid OBB files, but their names don't follow the convention Android expects. Your OBB file should have a name like the following: 

main.[VERSION_NUMBER].[PACKAGE_NAME].obb

Where [VERSION_NUMBER] is the highest digit of the version number you can find in the Player Settings:


And [PACKAGE_NAME] is the package name specified in the same screen, right above the version number:


So, in the example depicted in the images, the name of the OBB file would be:

main.1.com.iayucar.TestGame1.obb

2.- Copy the renamed OBB file to an specific location

The game will expect to find that OBB file in a location like:

[INSTALL_LOCATION]\Android\obb\[PACKAGE_NAME]

Where [PACKAGE_NAME] is the same value described above, and INSTALL_LOCATION refers to whether the game is installed in the internal memory or the external SD-Card (this depends on your own settings). 

As our game is configured to be installed in an external SD-Card preferably, the folder where we need to paste the OBB file is:

\\SDCard\Android\obb\com.iayucar.TestGame1\

And that's it. Now you can launch the game, and it will properly find the additional contents included in the OBB Expansion File. 

Happy 10th Birthday, GraphicDNA !

Last week this blog turned 10!!

Image result for 10th birthday

Can't believe how fast time goes by.

During this period, I founded my company, I had the honor to be awarded as DirectX MVP (4 years in a row), I became part of Microsoft / RARE team, and then I spent some of the best years I had in the industry, working as Associate Technical Director at Electronic Arts. It's been an amazing adventure being part of the development teams of all these games:

Credited on...

Now that I´m back to teaching, writing, developing and R&D projects, I'm certain that the best is yet to come.

It's been a wonderful time to be a developer all along, so let's see what the next 10 years bring :)

Cheers!

Custom MainLoop in C# / UWP applications with DirectX (SharpDX) with unlocked frame rates (beyond 60 Hz)

When you want to write a game or a 3D application in C# using SharpDX, and you want it to be UWP, there is little information about how to correctly handle the basics of the main loop.

All examples I found were based on the interop between XAML and DirectX, but if you go that path, you´ll need to rely on the CompositingTarget.Rendering event to handle your updates and renders, which lets all the inner processing to Windows.UI.XAML and limits the frame rate to 60 Hz.

So, how to create your own, unlocked-framerate-ready, main loop?

First things first:

Dude, where's my Main entry point?

Typically, a C# application has a Program static class where the "main" entry point is defined.

When you create a WPF, UWP or Windows Store application though, aparently that code is missing, and the application is started magically by the system.

The truth is that the main entry point is hidden in automatically-generated source code files under the obj\platform\debug folder. If you look there for a file called App.g.i.cs, you'll find something like this:


#if !DISABLE_XAML_GENERATED_MAIN
    /// <summary>
    /// Program class
    /// </summary>
    public static class Program
    {
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 14.0.0.0")]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        static void Main(string[] args)
        {
            global::Windows.UI.Xaml.Application.Start((p) => new App());
        }
    }
#endif

Et'voila... There's your entry point.

So first thing is to define the DISABLE_XAML_GENERATED_MAIN conditional compilation symbol to prevent Visual Studio from generating the entry point for you.

Next, is to add your own Program class and main entry points, as always, so you have control on the application start procedure. You can simply copy-paste that code anywhere in your project.

The Main Loop

Please note: this implementation is inspired by the C++ equivalent described here.

Now that you have a main entry point, you can replace the invokation of Windows.UI.Xaml.Application.Start (which internally deals with its own main loop) with your own code.

What we want to use instead is: Windows.ApplicationModel.Core.CoreApplication.Run, which is not bound to XAML and allows you to define your own IFrameworkView class, with your custom Run method.

Something like:


public static class Program
{
    static void Main(string[] args)
    {
        MyApp sample = new MyApp();
        var viewProvider = new ViewProvider(sample);
        Windows.ApplicationModel.Core.CoreApplication.Run(viewProvider);            
    }
}

The ViewProvider class

The main purpose of the view provider is to create a IFrameworkView when required, so it could be something like this:


public class ViewProvider : IFrameworkViewSource
    {
        MyApp mSample;

        public ViewProvider(MyApp pSample)
        {
            mSample = pSample;
        }
        //
        // Summary:
        //     A method that returns a view provider object.
        //
        // Returns:
        //     An object that implements a view provider.
        public IFrameworkView CreateView()
        {
            return new View(mSample);
        }
    }

The View Class

The view class implements the IFrameworkView interface, which defines most of the logic we want to implement.

The framework will invoke interface's methods to perform the initialization, uninitialization, resource loading, etc, and will also report us when the application window changes through the SetWindow method.

For the purpose of this article, the most interesting part is the Run method, which we can write to include our own, shiny, new Main Loop:



public void Run()
{
    var applicationView = ApplicationView.GetForCurrentView();
    applicationView.Title = mApp.Title;

    mApp.Initialize();

    while (!mWindowClosed)
    {
        CoreWindow.GetForCurrentThread().Dispatcher.ProcessEvents(
                                   CoreProcessEventsOption.ProcessAllIfPresent);
        mApp.OnFrameMove();
        mApp.OnRender();
    }
    mApp.Dispose();
}

This removes the need to rely on XAML stuff in your game (and its overhead), gives you more control about how the mainloop behaves, and unleashes the possibility of rendering with a variable frame rate in C#.

Please refer to this page for further info about how to initialize a swap chain suitable for unlocked frame rates.

Hope it helps!

[UWP] Unable to activate Windows Store app - The app didn't start


Today, I've been struggling with a Visual Studio 2015 deploy error for a while.

When trying to debug a C# - UWP application, I kept receiving the following error upon application activation:


Places like this have information about other people finding the same error. Some of them even re-installed Windows 10 from scratch with no luck.

In my case, the cause (and solution) was much simpler than that:

I have my all my projects in an external SSD drive. Yesterday I was working in my laptop, and the last compilation I did there was in Release mode. When I brought the external disk back to my main PC today and tried to deploy directly as Debug, the activation failed for some reason.

So, going back to Release mode, rebuild, launch and let Windows activate the app did the trick. After that, I've been able to go back to Debug mode normally. 

Hope it helps.