iOS and Android: Creating A Simple Extension

In this article we are going to take you through the steps required to make an extension for the Android and iOS target platforms. Before continuing you should note that a working knowledge of Objective C for iOS extensions and Java for Android extensions is required, as well as a good working knowledge of GML (the GameMaker Language).

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 an object and a sprite to the resource tree. 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. Here you only need to name your extension and give it a version number, then check the Android and/or iOS export checkboxes from the platform list to show that we are creating an extension for those platforms, and uncheck all the "Copies to" options except Android and/or iOS (note that if making an Android extension, this will be compatible with the Amazon Fire export too, so that can also remain checked if you require it) :

Extensions_1.png

 

The iOS Window

To start with, we'll look at the iOS window. Here you can give various different bits of information that will govern how your extension works and what it includes. The available sections are:

  • Compiler Flags / Linker Flags: Some frameworks and third party SDKs require the addition of extra linker flags and compiler flags to work. These can be specefied here (see the documentation that accompanies the SDK or framework you are using for more details).

  • ClassName: Your extension can have multiple classes, with each class having its own list of 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.

  • System Frameworks: Here you can add in any iOS system frameworks to your extension.

  • 3rd Party Frameworks + Bundles: This section is for adding third party frameworks and SDK bundles.

Below is an image of how the tab would look when using a third party SDK:

iOS_Extension_Example.png

The two sections at the bottom of this window 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). To add framework/SDK information here you must first click the (+) button to create a "placeholder". You can then slow left-click on this and rename it to the correct name for your framework, and if the framework requires a weak linking then you can click the checkbox next to the framework name. With that done, you need to add the files to the extension, either from a Mac or from a PC, using the framework path or Add Source button at the bottom of the window.

For our simple extension you only need to give the class name "GenericTest" however, and can leave the other options blank.

 

The Android Window

When you click the Android checkbox, you'll open the Android extension options window. Here, like with iOS, you need to give a Class Name and add in the information that the Java or SDK requires. This information is comprised of the following:

  • 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.

  • 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 button to add a placeholder permission, and then do a slow click on that to edit it to what is required. You can remove permissions using the 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. Make sure to revise this (and your permissions) carefully before submitting any games to the store, as incorrect settings will cause your game to be failed for submission.

  • Inject to AndroidManifest.xml Application: 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. Make sure to revise this (and your permissions) carefully before submitting any games to the store, as incorrect settings will cause your game to be failed for submission.

  • Inject to AndroidManifest.xml RunnerActivity: 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. Make sure to revise this (and your permissions) carefully before submitting any games to the 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_Extension.png

However, for our example you can leave all these blank, and simply set the class name to "GenericTest" then continue.

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 the following:

  • 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 2 to add them to the extension. To do this you need to do the following for the different platforms:

  • For iOS - You will want to use either the Enter framework path (+) or the Add Source section of the iOS window (depending on whether the downloaded source files are on Mac or PC), and then browse to the folder containing the .mm and .h files.

  • For Android - Click the Add Source button and browse to the folder where you downloaded the .java file.

Once you have done this, you won't see any obvious changes to the GameMaker Studio 2 windows, but the files will have been added to your extension. You can check this easily by right-clicking the extension in the resource tray and selecting Open In Explorer. When the explorer window opens, you should see folders for each of the added files, called AndroidSource and iOSSource:

 Explorer.png

If you then open those folders, you should find the files you downloaded for the extension. All files added to an extension will go in one of these folders based on the OS the extension is for.

 

Creating the GML Functions

Next you need to add the function declarations to the extension so that your code can use it in your games. To do this, first close the iOS and Android extension properties and then in the main extension editor click the Files selector and add a placeholder file:

AddPlaceholder.gif

The "placeholder" is simply the top level folder of the functions and constants and can be renamed by slow clicking on it and giving it a new name. If you double-click on it, then you will get the placeholder Properties window - where you can also rename the placeholder - and here is where we'll be defining the functions for the extension.

Extension_Properties.png

To add the functions, simply go to the Functions section of the window and click the menu bar then select Add Function:

AddfUNCTION.png

This will open the function properties window where we can start to define the functions for the extension. Note that both of the platforms (iOS and Android) will be using the same functions, and if you study the downloaded files using any text editor - like Noteplad++, for example - you will see that the source files share the same function names for everything.

The functions we will be adding are as follows:

   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: string

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

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

Here is an example image of how one of the functions should look with the details filled in:

ExampleFunction.png

When you've added all the functions given above, 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 regular GML 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));
 

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"]);
    }

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, with code something like:

draw_self();
draw_text(32, 32, result1);
draw_text(32, 48, result2);
draw_text(32, 64, result3);
draw_text(32, 96, result4);

 

Testing

You can now test your project on an Android and/or iOS device and see that the extension functions are working correctly. 

 

 

 

 

Have more questions? Submit a request

0 Comments

Article is closed for comments.