Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more

Tech

Creating A Simple Extension For iOS And Android

Posted by Mark Alexander on 11 July 2014

Extensions for iOS and Android were first introduced in the 1.3 beta version of Gamemaker: Studio. With the advent of the 1.4 version, the process for creating them has changed somewhat to make things easier and more streamlined. So, in this Tech Blog, we are going to take you through the steps required to make an extension for those platforms. It is worth noting that you will be required to have a working knowledge of Objective C for iOS extensions and Java for Android extensions as well as a good working knowledge of GML (the GameMaker Language).

Note: For an overview of how basic Windows extensions work, please see the article Creating An Extension For Mac, Windows, And JS Targets. If you are new to extensions it is recommended that you read this article too.

Getting Started

Before going any further, you should first create a new project and call it "GenericTest", then add a room, an object and a sprite. We are keeping this simple, so all we want is a "button" sprite which can be assigned to the object, and the object should be placed in the room. This button will call our new native extension functions.

Create The Extension

We now need to create our extension. This is done by first right clicking on the Extensions folder in the resource tree and selecting "Create Extension", which will bring up the Create Extension window and here you only need to name your extension and give it a version number, then check the Android and iOS export checkboxes from the platform list (normally you'd check both the normal and YYC options, but it can be one or the other) to show that we are creating an extension for those platforms. Once you have done that you should click the Next button.

Extension Properties

The iOS Tab

After clicking Next you will be taken to the iOS tab where you can give the Class Name and add in information about your frameworks (if you are only creating Android extensions you can skip this section). Here you can give the following details:

  • Linker Flags / Compiler Flags: Some frameworks and third party SDKs require the addition of extra linker flags and compiler flags to work which can be specified here (see the documentation that accompanies the SDK or framework in question for details).

  • ClassName: Your extension can have multiple classes, with each class having its own functions and constants, so you should give it a name that reflects its purpose.

  • Inject to Info.plist: Here you can add any code to be a injected into the info.plist file.

For our simple extension you only need to give the class name "GenericTest", and can leave the other options blank. Below is an image of how the tab would look when using a third party SDK:

ios_Properties

You can see two further windows at the bottom of this tab. These are provided so that you can add any iOS system frameworks or third party frameworks to your extension (see the documentation that came with your chosen SDK for info on the framework name), and when you add any of these you can set them to use set weak references or not. To add framework/SDK information here you must first have added the appropriate files to the extension, and although our test extension needs none of this, we'll briefly explain how this can be done...

To add a framework you need to right-click on the extension and select Add iOS Framework From Mac and then browse to the files you wish to add. Added files will be stored in the iOSSource directory along with your extension. You can open this location at any time by right-clicking on the extension and selecting Open Extension Directory.

For our example you can leave these blank and then click on the Android tab to give the required information for that platform (if you are only testing on iOS, you can click the Create button at the bottom to create the base extension, and skip the next step for Android).

The Android Tab

After clicking the Android tab you will be shown the Android propertied where you can give the Class Name and add in information that your Java or SDK requires. This information is comprised of the following:

  • Android Permissions: Here you can add in any extra permissions that your extension requires. What these permissions are will depend entirely on the use that the extension has, and so you should check the documentation supplied by Google for the Android platform, or, if you are using a third party SDK, the documentation that comes with the SDK. To add a new permission you need to click the Add button to open the permissions dialogue where you supply the permission details. You can remove permissions using the Remove button.

  • Inject To Gradle Dependencies: Here you can add any extra code that needs to be injected (added) into the Gradle build dependencies.

  • Inject to AndroidManifest.xml Manifest: Here you set any extra code to be injected (added) to the Android Manifest XML file when your game is built for testing or final release.

  • Inject to AndroidManifest.xml - Application Level: Here you set any extra code to be injected (added) to the Android Manifest XML file under the Application heading when your game is built for testing or final release.

  • Inject to AndroidManifest.xml - RunnerActivity Level: Here you set any extra code to be injected (added) to the Android Manifest XML file under the RunnerActivity heading when your game is built for testing or final release.

What permissions are required will depend entirely on the use that the extension has, and so you should check the documentation supplied by Google for the Android platform. If you are using a third party SDK, check the documentation that comes with the SDK before filling in anything here. Make sure to revise both the permissions and the XML code carefully before submitting any games to the Google Play store, as incorrect settings will cause your game to be failed for submission.

Below you can find an example image of how this tab would look when using a third party SDK:

Android Properties

However, for our example you can leave all these blank, and simply set the class name to "GenericTest", then click the Create button at the bottom to create our base extension.

Adding The Native Source Code

Once you have created the extension, you will need to add the required files for your it to work. So, let's create a some files with our source code to add for both platforms. Our extension will do several things:

  • It will return two numbers added together.
  • It will return a string made up of an input string and an input value.
  • It will return a string made up from two input strings
  • It will return values to the Social Asynchronous Event

Rather than post the various sections of code here, we have made the files available for download below:

For android: GenericTest.Java

For iOS: GenericTest.mm GenericTest.h

Once you have downloaded these files to a location on your hard disk, you can go back to GameMaker: Studio 1.4 to add them to the extension. To do this you need to right click on the extension and select:

  • For iOS - either Add iOS Framework From Mac or Add iOS Source Directory and then browse to the directory containing the files you wish to add. In this case we want to choose Add iOS Source Directory and browse to the directory where we saved our files. Added files will be stored in the iOSSource directory along with your extension.

  • For Android - either Add Android SDK or Add Android Source and then browse to the directory with the files you wish to add. In this case we want to choose Add Android Source and browse to where we saved our Java file. Added files will be stored in the AndroidSource directory along with your extension, with the component parts split into sub-directories as required (for example the full path to our extension files would be *AndroidSource/Java/GenericTest.

Once added these files can be edited directly from the source directory location with any changes being detected automatically by GameMaker: Studio 1.4. You can open this location at any time by right clicking on the extension and selecting Open Extension Directory.

Creating the GML Functions

Next you need to add the function declarations to our extension in GameMaker: Studio 1.4 so that your code can call your new extension. To do this, right click on the group file "GenericTest.ext" that we added earlier, and select Add Function. This will open a new window where you can add your function and assign it arguments and properties. The image below shows an example function:

Both of the platforms will work using the same functions, and if you study the files supplied above (using any text editor, like Noteplad++, for example), you will see that the Android and iOS source files share the same function names for everything. We should add these functions into Gamemaker: Studio now, making sure that they match the details given here:

   function / external name: AddTwoNumbers
   help: AddTwoNumbers(value1 , value2);
   arguments: double, double
   return type: double

   function / external name: HowManyObjects
   help: HowManyObjects(value1, value2, string);
   arguments: double, double, string
   return type: double

   function / external name: BuildAString;
   help: BuildAString(string1, string2);
   arguments: string, string
   return type: double

   function / external name: ReturnAsync
   help: ReturnAsync(value1, value2);
   arguments: double, double
   return type: double

With those added, we can start to program our test game to use them!

Calling The New Extension Functions

Our new extension functions can now be used just as you would any of the built in GameMaker: Studio functions, and if you have added the "help" string then your function will also appear in the auto-complete and syntax checker. To call our functions we need to create an object and assign it a sprite, then add a Create Event to initialise the variables required:

result1 = "!! Not run !!";
result2 = "!! Not run !!";
result3 = "!! Not run !!";
result4 = "!! Not run !!";

You can now add in a Mouse Left Pressed Event with the following code:

result1 = string(AddTwoNumbers(irandom(100), 50));
result2 = BuildAString("Hello", "World");
result3 = HowManyObjects(irandom(1000), irandom(1000), "Targets");
ReturnAsync(irandom(1000), irandom(1000));

You should also add a Draw Event to show the result variables on the screen so that you can see whether the extension has worked.

The ReturnAsync() function will require that you add a Social Asynchronous Event to the object, as it will be triggered by the function. This is a useful way to return information as it will permit the game to continue running and other things to happen while the extension is processing or retrieving data. In this event we can have the following code:

var type = async_load[? "type"];
if type == "finished"
{
result4 = "value1: " + string(async_load[? "argument0"]) + ", ";
result4 += "value2: " + string(async_load[? "argument1"]);
}

The Export Options

You should also set the export options for the extensions that you make. This ensures that your files will only be exported with the final executable for the appropriate target platform. To set this, you need to right-click on the GenericTest.ext file in the resource tree and select Properties. un-check everything except Android and iOS.

FileProperties.png

You can still test your game on other targets and your functions will be replaced by "dummy" functions for the platforms other than iOS and Android. It is recommended that you do an os_type check and only call the functions when the appropriate os is detected, since the return values may differ on those platforms that the extension is not designed for.

Testing

You should now be able to test your game on an Android and/or iOS device and see that the extension functions are working correctly. Note that testing extensions on Android requires that you build a final APK, as just using the Test Play and Debug options form GameMaker: Studio will not work as the extension will not be compiled correctly. On iOS there is no such restriction, although you should have your device connected via USB to your Mac the first time you test.

Back to Top