In today's multiplatform world, developers must not only adapt their games for different operating systems, NDKs, App Store rules and input methods, but also account for major technical differences between the platforms. Fortunately, most of the hard work is done by ShiVa, which automatically selects the appropriate engine binary for you, compresses your textures and media to the correct formats, and creates ready-to-deploy archives with a few clicks. However if you plan on extending the engine through plugins, today's diversity in processor architectures and operating systems can make it very hard for any developer to get their plugins running on every targeted device. In this tutorial, we are going to have a look at Windows, OSX and iOS to see how you can make your plugins fit for a multiplatform world.
There is one simple rule to ShiVa engine plugins: The architecture of the engine must match the architecture of the plugin. If you plan to publish a 64bit version of your game, all your plugins must also be compiled as 64bit binaries. And while it is possible to run e.g. 32bit games on 64bit Windows, you cannot mix architectures within the application itself.
This creates a problem. Most users do not know about the processor architecture of their devices, so they are confused which version of your game they are supposed to download - 32bit, 64bit, arm, x86, ppc? It is also not comfortable for the developer to recompile and repackage everything many times over just to support multiple architectures. In most App Stores, having multiple versions of the same game for different architectures is also not allowed, or having a universal binary application is a requirement for app admission. Luckily, ShiVa allows you to pack multiple plugin builds into one STK, so you can support a large number of systems with just one game pack.
We start by opening up a plugin project as it comes out of ShiVa by loading the solution into Visual Studio. The SLN file is located in the Windows / WinRT branch of the plugin project.
You need to make sure that all architectures you want to build for are enabled for the project. To do that, right-click on the solution and select "Properties":
Open the Configuration Manager and make sure that at least "Win32" and "x64" (for Windows Desktop) or "ARM" (for ARM-based Surface tablets and Windows Phone) are selected.
If you did everything correctly, you can select the target architecture for your build from the Solution Properties:
You can now build your plugin DLLs. Since Windows does not support multiple architectures in one dll, you have to create one individual DLL for each platform. ShiVa expects its plugin DLLs to be in the Contents directory:
But depending on your settings and version of Visual Studio, you might also have to locate, copy and (re)name the DLL from the Windows build directory and put it into your plugin project Content directory:
Since you have to build individual DLLs for each platform, name them appropriately. A good practice would be adding suffixes like _32, _64 and _arm.
OSX and iOS libraries
The process for OSX and iOS in Xcode is similar, but has some important differences. We start again by loading the xcodeproj into Xcode. It is located in the MAKE directory as well, although in the Mac (and iOS respectively) branch.
Xcode will most likely present you with several steps on how to improve your project to make it work more smoothly with the current version of Xcode. You should accept these changes:
The architecture settings are hidden behind the Build Settings tab -> Architectures. For OSX, you should switch to Universal (32/64-bit Intel), which builds for both x86_64 and i386 architectures. Unlike for Windows, OSX and iOS can pack multiple Architectures into one single library (universal binary).
To build both architectures and not only the one that matches your system, switch off Build Active Architectures Only:
After building your universal library, you can check the success by opening a terminal and using FILE on the plugin. It should list all supported enclosed architectures:
iOS requires ARM architectures, and there are a great number of them to choose from. Luckily for ShiVa iOS, you only need two: armv7 and arm64. Since February 1st 2015, Apple requires you to support both architectures in newly released iOS application, so this step is really not optional. Select Standard Architectures here again and you are on your way.
With all your plugin libraries built successfully and copied to their appropriate locations in the Content directory, you must now tell ShiVa how these files are named and which architectures they support. This is done through an XML file located in your ShiVa plugin directory:
The PLATFORM > FILES section is the one that we need to have a closer look at. Remember how we needed to compile separate DLLs for Windows/WinRT? Now is the time to declare them:
Appropriate choices for Windows/WinRT are x86_32 (32bit Desktop Windows), x86_64 (64bit Desktop Windows), and arm_32 (32bit ARM for old Surface and Windows Phone). For OSX and iOS, this are a little different. If you followed this tutorial, all your different architectures are in a single file, so you need to declare the same plugin file over and over again until you have gone through all the supported platforms:
OSX has had a much more interesting past than Windows when it comes to processors, so there are more architectures to take care of - but really the only ones you need are x86_32 (32bit) and x86_64 (64bit). Power PC (ppc_32 and ppc_64) are legacy platforms that have not been supported by Apple for many years, and ShiVa does not ship with those engines by default anyway.
iOS is also potentially powered by a wide range of processors with different architectures. Apple has stopped supporting most of them except for armv7, armv7s and arm64. And since February 1st 2015, Apple requires you to support both armv7 and arm64 in newly released iOS application, so both your plugins and your applications have to be built with ARCHS_STANDARD. One important thing to note is that Xcode declares its architectures without underscores (armv7, arm64), but ShiVa has to have an underscore (arm_v7, arm_64). Possible values for your Manifest.xml are: arm_v6 (deprecated by Apple, for very old iPhones and iPod Touches), arm_v7 (32bit A4, A5, A6), and arm_64 (A7+). Supporting arm_v7s is not required.
With your plugin files all declared properly, save the XML file. When you export your STK next, every plugin file should be pulled into the archive and accessed by your game automatically based on the architecture of the system.
To summarize, let us go through the most important systems and list the supported and/or required architectures you can/have to build for.
- Windows Standalone: separate 32/64bit DLLs, matching engine binary. 64bit systems can run 32bit games.
- Windows RT: separate 32/64bit DLLs, matching engine binary. ARM for Phone/old Surface. 64bit systems can run 32bit games.
- OSX: universal 32/64bit libraries. OSX engine currently only 32bit. 64bit systems run 32bit games. ppc obsolete.
- iOS: universal armv7/64 libraries. Universal games are a requirement for the AppStore. v7s not required. v6 osbolete
- Linux: separate 32/64bit libraries, matching engine binary. 64bit systems cannot run 32bit games without additional libraries (most likely not installed/available).
- Android: 32bit libraries only, as Android64 is still in its infancy. Use JAVA when possible (Android plugin tutorial)
- Consoles: Build only for the actual console architecture.