In this article we will take you through the steps required to integrate Facebook with your Android, iOS and/or HTML5 game using the YoYo Games Facebook extension.
Before continuing, you will need to have a Facebook Developer account, which can be set up from the following link:
Create The App ID
Once you have created your developer account, the first thing you'll need to do is add your game to it and get an App ID for it. For that, simply hover over the My Apps menu link and then select Add New App:
You will then be presented with a screen asking you to supply a Display Name for the game as well as a Contact Email (note that you cannot use "face" or "facebook" as part of the display name) :
Once completed, you need to click the Create App ID button to continue.
After you create an app ID, you will be taken to your app Dashboard. In the left-side navigation panel of the Dashboard, you should now click Settings > Basic to view the App Details Panel with your App ID, your App Secret, and other details about your app:
You should take note of the App ID and App Secret as you'll need them later in GameMaker. Now, take a moment to update or change the name, email, and other details of your app:
- App Name - A name has been supplied but change this to the name you prefer.
- Contact Email - A contact email for this app.
- App Domains - Provide the Google Play and/or Apple App Store URL of your app.
-
Privacy Policy URL - You must provide a Privacy Policy URL. Must be provided to take your app public.
- Terms of Service URL - You can provide a Terms of Service URL here.
- App Icon - Artwork or image used to identify your app (1024x1024 png or jpg).
- Category - Choose the category type for your app.
Next, you will be presented with the Data Protection Officer's Contact Information. This is a requirement under GDPR by European Law and you should fill in the required details. When finished you can then click the Add Platform button at the bottom:
Here you should choose either iOS, Android or Website if you are publishing an HTML5 game.
iOS
Selecting iOS will open the setup window for iOS devices to use your app. You will need to have set up an iTunes listing for your game and have a Bundle ID and an App ID (see the Apple documentation for more information) which you will need to add in here (make sure that the Bundle ID matches that of the iOS Game Options for your game):
You can ignore the rest of the options in this window and continue on to add details for the Android version of your game. If you aren't adding Android or HTML5 for now, scroll to the bottom of the page and click Save Changes.
Android
Selecting Android will open up the setup window for Android devices. You will need to have set up a Google Play store listing for your game and will need your Package Name and Key Hash. The package name is the reverse URL identifier used for your game on the Play Store (and it should match that used in the Android Game Options for your game). You can get the hash key from the Android Preferences Keystore section. Use them to fill in the Android options:
Note that you also need to add a Class Name which should be formatted as:
<Your_Package_Name>.RunnerActivity
As shown in the screenshot above.
You can ignore the rest of the options in this window and scroll to the bottom of the page where you should click the button labelled Save Changes, unless you want to set up a website with an HTML5 game.
Website (HTML5)
If you choose Website, then you have two options, depending on whether you want to test your game running it from GameMaker, or whether you want to have the game hosted "live" on a server.
For testing the game from GameMaker, you need to set the Site URL to
http://localhost:51264/
Then go to the Basic game settings and set the App Domain to localhost:
This will permit you test your game when running it from within GameMaker Studio.
If you want to host it on a server as a published game, then you'll be required to fill in the Site URL so it points to the location of your game. Note that Facebook will require your game to be hosted on a site with a valid SSL certificate and the link should be HTTPS.
With that done, you can now click Save Changes and move on to setting up GameMaker.
GameMaker
Now in GameMaker, the first thing you need to do is add the Facebook extension to your project. For that, you need to add the extension to your account on the Marketplace. Once added, go to Marketplace -> My Library in GameMaker and then download and install the Facebook asset (you can find it easily using the search function):
You should now open the Facebook extension asset from the Asset Browser (FacebookExtension2):
First of all, make sure that it's going to be exported only to those platforms where you are going to use it:
Now open the menu for your target platform under "Extra Platforms" (Android/iOS) and add your Facebook app details in the Code Injection window. You can find any relevant app details under Settings -> Basic on your Facebook dashboard.
Android
Add your Facebook App ID as the facebook_app_id string and as the fb_login_protocol_scheme string as well (but with an "fb" prefix).
For example, if your facebook_app_id is 12345, your fb_login_protocol_scheme should be fb12345.
iOS
Here add your FacebookAppID, your FacebookClientToken (which you can get from your Facebook dashboard under Settings -> Advanced -> Client Token) and FacebookDisplayName (which is the name of your application).
In the last box, add your Facebook App ID but with an "fb" prefix (for example, if your FacebookAppID is 12345, enter fb12345).
Once you've done that, if you are building for iOS or HTML5 then you can close the extension now and continue. However, if you are building for Android then you should go to the General section of the Android Game Options now and set up the API levels to use. The Facebook extension requires the following API settings as a minimum to work:
- Build Tools: 26.0.2
- Support Library: 26.0.0
- Target SDK: 26
- Minimum SDK: 19
- Compile SDK: 26
Once you've filled that in (and made sure you have the relevant APIs installed in Android Studio), you can continue on to add the code that will access the Facebook API.
IMPORTANT! The extension comes with a manual in PDF format as part of the "Included Files". If you require more in-depth details of the functions outlined in this article, then please see that document.
Adding Facebook Functions
When adding Facebook integration to your game, we recommend that you create a persistent controller object that will be added to the very first room of your game and persist throughout. This is because a lot of the Facebook functionality is asynchronous and so it's better to have a single object that is dedicated to dealing with the different callbacks, although your buttons and things don't themselves have to be persistent. The rest of this tutorial assumes you have such an object in your game.
Logging In
To start adding Facebook functionality to your game you will first need to ensure that the extension is installed correctly and set to export to the supported platforms. The extension contains the function fb_init() but this is called automatically as part of the initialisation process for the extension, so you should not call this in your projects.
Now, in the Create Event of the controller, we'll also initialise some variables that we'll need later as well as create a DS list with the basic permissions required (more on this later) and some variables to control the different permission requests:
fb_init();
fb_logged_in = false;
fb_read_permissions = false;
fb_publish_permissions = false;
fb_userid = "";
fb_username = "";
fb_picture = -1;
fb_permissions = ds_list_create();
ds_list_add(fb_permissions, "public_profile", "user_friends");
Once you've called that, you can then check that the Facebook Graph API has initialised correctly using the extension function fb_ready() (in an alarm or the step event). This will return true or false depending on whether the graph API is initialised or not, and can be checked before changing the room or starting the game proper. Once it returns true, you can then call the function to log the user in.
Normally you wouldn't log the user in automatically on game start - although you can - but instead have a button in the game that the user can press to log in and use Facebook. However you do it though, you'll need to call the extension function fb_login(). This function requires you to supply a DS list with the permissions that you want to have for the user logging in.
IMPORTANT! You can only request the default read permissions with this function. If you require additional read or write permissions after logging in you will need to specifically request them (see the Additional Permissions section, below). Also note that if your game requires more than the "public_profile", "email" and/or "user_friends" it will require review by Facebook before it can be used by people other than the game's developers.
The actual login code will look something like this:
if fb_status() != "AUTHORISED"
{
var perms = ds_list_create();
ds_list_add( perms, "public_profile", "user_friends");
fb_login(perms, fb_login_default);
ds_list_destroy(perms);
}
On Android, the "login type" argument is ignored, but on iOS this must be set to one of the GML constants outlined in the PDF manual that accompanies the extension. In general, you're fine just leaving it as fb_login_default. Note that we first check to see if the game has already been authorised since the login state can be persisted over various runs of the game, and if not then we log the user in.
NOTE: You can check the different status results and react in different ways depending on what is returned. We don't cover that in this article to keep things simple, so check the included PDF manual for more information.
When you call this function, it will generate an Asynchronous Social Event with the results of the login attempt. In this event, the async_load DS map will contain a "type" key, which will be the string "facebook_login_result" when the event is triggered by logging in. There will also be a "status" key which returns whether the login was a "success", "failed" or was "cancelled".
If the login status key is "success", then the user has logged in and you can go ahead and check each of the permissions you have requested to see if they have been "granted" or not.
You can check this with the following code:
switch (async_load[? "type"])
{
case "facebook_login_result":
show_debug_message("facebook_login_result async event triggered");
if async_load[? "status"] == "success"
{
if !fb_logged_in
{
fb_logged_in = true;
show_debug_message("User successfully logged in!");
for (var i = 0; i < ds_list_size(fb_permissions); ++i;)
{
var _key = fb_permissions[| i];
if ds_map_exists(async_load, _key)
{
if async_load[? _key] == "granted"
{
show_debug_message("Permission " + _key + ": granted");
}
else show_debug_message("Permission "+_key + ": "+async_load[? _key]);
}
else show_debug_message("Permission " + _key + ": Does Not Exist");
}
}
}
else show_debug_message("Login failed: " + string(async_load[? "status"]));
break;
}
The above code looks complex, but all it's doing is checking to see if the event was triggered by a login, and if it was then it parses the async_load map and outputs the permission and whether it was granted or not. In general, you don't really need all that code, but we've added debug messages in to cover every eventuality so that you can see whether the code is working (or not!) in the console output. Note that there are further keys returned in the async_load map, which are explained more fully in the PDF manual.
Getting User Data
Once the user has logged in you can start to do graph requests to get more information about them, which you can then incorporate into your game. To formulate a graph request you'd use the function fb_graph_request(), something like this in the controller Asynchronous Social Event, when the login has been confirmed (you could also add it to a key or mouse press event):
var _l = ds_list_create();
ds_list_add(_l, "fields", "id,name,picture");
fb_graph_request("me", "GET", _l);
ds_list_destroy(_l);
So, here we first create the request DS list, and then we populate it with the parameters required for our chosen node, where each list entry follows the pattern of "key, value, key, value, etc...". A more complex example could be:
var _l = ds_list_create();
ds_list_add(_l, "id", "123", "name", "John Doe", "picture", "http://url-to-picture.jpg");
In the case of our test code, we're targeting the "/me/" node, which means that all data you retrieve comes from the logged-in user.
NOTE: A node is an individual Facebook object with a unique ID. For example, a single user, the logged-in user or a business would all be considered nodes. Returned data for the different nodes will be limited by the permissions requested and set on the account targeted.
So, we populate the list with the data we want to request then call the fb_graph_request() function as a "GET" call, supplying the map data.
IMPORTANT! With the basic permissions, you can only request very specific data from the open graph. You can find a list of available default requests here.
In the Social Asynchronous Event event again, we need to retrieve the data from the DS map and use it to set some variables. For this, we'll simply add a new case into the switch that checks for "type":
case "fb_graph_request":
show_debug_message("fb_graph_request async event triggered");
if async_load[? "status"] == "success"
{
show_debug_message("Graph Request Successful!");
var _text = async_load[? "response_text"];
var _response = json_decode(_text);
show_debug_message("Response = " + string(_response));
fb_username = _response[? "name"];
fb_userid = _response[? "id"];
var _pic_map = _response[? "picture"]
var _data_map = _pic_map[? "data"];
fb_picture = sprite_add(_data_map[? "url"], 0, false, false, 0, 0);
}
else
{
if async_load[? "status"] == "error"
{
show_debug_message("Graph Request Error!");
show_debug_message("Exception = " + string(async_load[? "excepton"]));
}
else
{
show_debug_message("Graph request Cancelled!");
}
}
break;
Here we use the returned data to set the variables that hold the user name and user ID. These can then be used to display personalised messages and content in your game. Note that we also extract the "data" map from the "picture" key and then use that to create a new sprite for the user avatar. In this case, the variable only holds the request ID as loading the picture will be handled by the Asynchronous Image Loaded event, which you would deal with as follows:
if async_load[? "id"] == fb_picture
{
if async_load[? "status"] >= 0
{
sprite_index = fb_picture;
}
}
All that does is take the returned avatar sprite and set the user profile to use it. Don't forget that this sprite will need to be deleted when no longer required (using sprite_delete()).
Graph requests are a very powerful tool and this is just one example of how to use them to get data. However we can't go into all the details of each and every node here, so we recommend that you check the extensive documentation on the Facebook developer pages, as well as the Graph API Explorer, which lets you test nodes and see what data is returned, etc...:
Also, note that the Facebook Extension Demo project also shows different uses of the graph request function to get friend's data and delete permissions among other things.
Additional Permissions
It may be that your game requires additional read or publish permissions, so you'll need to request these and have the user agree to grant them. For this, we use the functions fb_request_read_permissions() and fb_request_publish_permissions(). Now, before continuing, it's very important to note that these functions will log the user into Facebook again, and so if any of the permissions are not granted or there is an error, the function fb_status() will return "FAILED", but the user will still be logged in, they just won't have the requested permissions.
In general, you'd want to request additional permissions directly after getting a successful user login callback in the Social Asynchronous event, so that's where we'll be adding the following code, after the initial fb_logged_in check, in the same async type, "facebook_login_result":
case "facebook_login_result":
show_debug_message("facebook_login_result async event triggered");
if async_load[? "status"] == "success"
{
if !fb_logged_in
{
// Login code shown above here
}
if fb_logged_in
{
if !fb_check_permission("user_birthday")
{
var _list = ds_list_create();
ds_list_add(_list, "user_birthday");
fb_request_read_permissions(_list);
ds_list_destroy(_list);
show_debug_message("Requesting READ permissions - user_birthday");
}
else
{
show_debug_message("READ Permission Granted");
fb_read_permissions = true;
if !fb_check_permission("publish_to_groups")
{
var _list = ds_list_create();
ds_list_add(_list, "publish_to_groups");
fb_request_publish_permissions(_list);
ds_list_destroy(_list);
show_debug_message("Requesting PUBLISH permissions - publish_to_groups");
}
else
{
fb_publish_permissions = true;
show_debug_message("PUBLISH Permission Granted");
}
}
}
}
else show_debug_message("Login failed: " + string(async_load[? "status"]));
break;
As you can see from the code above, we first check to see if the user already has the required read permission and if they don't we request it. This will trigger another login Social Async Event, where we can check to see if the permission was granted and then request publish permissions (which in turn will trigger another Social Async Event).
NOTE: The "publish" permissions are pretty much obsolete and only used for some very specific things. In general, you can ignore them and simply request read permissions.
For a full list of the permissions that you can request, see this Facebook Developer article:
Posting To Facebook
You now have your user data as well as the permissions you require for your game. you can use the user data to interact with the user by applying their avatar to achievements, or in-game identifiers etc... but you may also want to let the user share information about the game with other people on Facebook. For that, we have the function fb_dialog().
This function can be called from anywhere in your game and would look something like this:
if fb_status() == "AUTRHORISED"
{
fb_dialog("http://link.com");
}
A few things to note when using this function:
- The user does NOT have to be logged in when it is called, as the function will request the user log in if they're not already.
- The URL you supply should link to a page related to the content being shared.
- The dialog message will be populated using the Open Graph meta tags embedded in the header of the URL you give. An example of this would be:
<meta property=”og:title” content=”Mesh - Fast Finger Fun!” />
<meta property=”og:url” content=”http://www.nocturnegames.com” />
<meta property=”og:description” content=”Mesh is a frenzied neon arcade game where quick fingers are needed to score points and combos as you try to beat your previous high scores!” />
<meta property=”og:image” content=”https://m.gjcdn.net/screenshot-thumbnail/900x2000/334601-v3.jpg” />For more information on Open Graph meta tags, please see here:
- The Open Graph Protocol.