The 1.3 update to GameMaker: Studio brings many new and exciting features to the program: SWF import, push notifications, and a re-vamped IAP system. However, arguably the most important part of this update is the opening up of the extension system to permit 3rd party SDKs and native code to be integrated into your games.
To start with, native extensions will only be available on the iOS and Android targets (with further target platforms to be added over time) and so this article will outline the general methods for adding extensions to your games for these platforms. Future platform additions shouldn't vary too much from the forms outlined here, however.
It should be noted that the iOS platform requires extensions to be written using Objective C++, while Android extensions are written using Java. This article assumes that if you are writing or using extensions for these platforms then you already have a working knowledge of the native language for the chosen target.
To create an extension in GameMaker: Studio is straightforward and requires you to first right-click on the Extensions folder in the resource tree and then click “Create Extension”.
This will bring up the Extension Package Properties window, where you should fill out the “name”, “author”, etc... fields for the extension you are creating in the General tab. With that done,
you should now fill in the details for the relevant platform you wish to develop for from their respective tabs. Note that one extension package can contain extensions for multiple platforms, so if you have a 3rd party SDK with files for Android and iOS, you can create one package that links to both, then set your configurations to only export that which is necessary (more on this later).
Each of the extension types require that you provide a ClassName for identifying them, and a Source Directory. This source directory is because extensions for the iOS and Android platforms don't require that you add any files directly into GameMaker: Studio as you would a JS extension or a DLL (although they do currently require a "dummy file" to work correctly, as explained later in this article). Instead you must "point" to your 3rd party folders or custom source files from this tab, and GameMaker: Studio will then compile the required files from them into your game.
Now, if you are creating an iOS extension, there are some extra fields which you may need to fill out: the Mac Source Directory should you have any SDK directory that requires symlinks, the Linker Flags since some frameworks and third party SDKs require the addition of extra linker flags to work, and finally any iOS system frameworks or third party frameworks that you need.
If you are working with Android, then there are only two other fields that you may need to fill in and that's the Permissions that your extension requires and any extra entries for the Android Manifest XML. The permissions you need will depend entirely on the use that the extension has, and you should check the documentation supplied by Google or the documentation that comes with the chosen SDK to find those that you need. As for the Android Manifest, this is where you add any extra information to the manifest that may be required for your extension, which will be injected (added) when your game is built for testing or final release.
The following are the basic steps necessary to create an iOS or Android extension and call a function using device native code, in this case we are adding a single new function to GameMaker: Studio that will, on iOS, use custom Objective C++ to output information to the iPhone Configuration Utility console on your development Mac, and on Android send the same information to the ADB Console.
Before going any further, you should first create a new room, a new object and a new 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 function.
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 Extension Package Properties window and here (for this simple example) you only need to fill in the General information, then click "Okay" to continue.
For JS, GML and DLL extensions you are required to supply a file containing the necessary code. However for iOS and Android, this file is not used but GameMaker: Studio still requires a file to "group" your extension functions and constants under (this may change in future updates). Therefore you should make a "dummy" file, which can be any format except .js, .gex, or .dll, and add that (call it something like "Extension.ext" for this example).
To add this file, you need to right click on the new extension and choose "Add File" then browse to where you created your "dummy" file and click the "Open" button at the bottom.
Now that you have prepared your file for grouping the functions and constants that you are going to use in your test game, we need to add the source Objective C++ files that the extension is going to use. For that, double click on the Extension Package folder and this time click on the iOS tab to bring up the properties for that target.
For such a simple example, you don't need to worry about any other details except the Source Directory and the Class Name, so just set them now. The folder directory is where we are going to store the necessary source files, and the class name can be something simple like "GenericExtension".
Now, in Windows Explorer, browse to the directory that you chose to locate your extensions source files and create a folder called "Source" (if you name it anything other than “Source” it will not be found by GameMaker: Studio). In this new folder you must create two files for your code – a .mm and a .h file. For this example we will call them GenericExt.mm & GenericExt.h. In your GenericExt.h file add the line
@interface YourClassName :NSObject
Now add a member function declaration corresponding to your desired functions – here we will use the following
-(void) genexttestdummy_Function1:(char *)arg1 Arg2:(double)arg2 Arg3:(char *)arg3;
Note the first parameter follows directly after the colon and does not need a name, but subsequent parameters need to be named "Argn" and they should then be followed by a colon and then the type (either double or char *) in brackets and finally the name that they will be referred to as in the function definition - arg2, arg3 etc...
After adding your member function declarations add "@end" to close the interface declaration.
In the .mm file we will firstly include the .h with:
then write the implementation of the functions that we are going to add – start with:
Add your functions as in the header file but, instead of ending the line with a semi-colon, add curly braces containing the code that you want to call – for our example we are calling NSLog to display the function call & parameters on the console which we will be able to view from the iPhone Configuration Utility on the Mac that our iOS device is connected to.
For an Android extension, things are somewhat simpler... We really only need to create the source Java file that the extension is going to use and “point” GameMaker: Studio to it, as, for this simple example, you don't need to worry about manifest details or permissions. So on the Android tab of the Extension Package properties window, just give a class name (like "GenericExtension")and set the folder where you are going to store your Java file for use.
Now, in Windows Explorer, browse to the directory that you chose to locate your extension’s source files in and create a folder called "Java" (if you name it anything other than “Java” it will not be found by GameMaker: Studio).
In this new folder you must create your Java code file and for this example you should simply create a file called "GenericExtension.java", remembering to include the following line at the top of your java code:
You can now create your class definition that includes the function that you desire to call. In our example you will need to create a class called "GenericExtension" with a member function that is called genextestdummy_Function1 that takes three arguments – String, double, string. For the sake of simplicity in this example just make your function log the parameters to the ADB console to verify that the function has been called correctly.
Next you need to add the function declaration to our extension in GameMaker: Studio so that your code can call your new Java function. To do this, right click on the group file that you added (the “dummy” file) and select “Add Function”. This will open a new window where you can add your function and assign its arguments and properties.
To match the code you created earlier, you should give the Function Name as "genextestdummy_Function1" and you should also set the External Name to be the same. Now set the three arguments that it takes (string, double, string) and click the "Okay" button to save the changes.
All that's left to do now is add a code box to our single "button" object in GameMaker: Studio to call our new function. In this example we have a single object, object0 that calls the defined function in the left mouse release event:
genexttestdummy_Function1("Hello", 100, "World");
Pressing and releasing this button when you test your game on a your chosen device should cause the passed parameters to be logged out to the iPhone Configuration Utility console on the Mac or to the ADB console on your PC.