FGL SDK User Guide

Welcome to the FGL SDK User Guide! This document will walk you through the steps to integrate and use the FGL SDK in your game, regardless of the framework you are using (HTML5, Unity, Godot, or LibGDX).

1. Introduction

The FGL SDK is a JavaScript library that allows you to integrate ads into your game. It is automatically loaded when your game is uploaded to the FGL game portal. However, you must initialize the SDK with your game's private key to enable its functionality.

Developers using frameworks like Unity, Godot, and LibGDX cannot modify frontend JavaScript directly. Instead, they must handle SDK initialization and interaction entirely within their framework.

2. SDK Initialization

To initialize the SDK, you must call the FGL.init() method with your private key. This must be done from within your game framework, as you cannot modify the frontend JavaScript directly.

2.1 Checking SDK Availability

Before initializing the SDK, ensure that it is loaded by checking for the presence of the FGL object in the global scope. This can be done using framework-specific methods to evaluate JavaScript code.

2.2 Initializing the SDK

Once you confirm that the SDK is loaded, call the FGL.init() method with your private key. Below are examples for different frameworks:

Unity (C#)

In Unity you first need to create some files to create the bridge between Unity + Javascript.

Step 1: Create the jslib file

Create a new file called FGLPlugin.jslib in your "Plugins" folder

Add the following code:

<code>
mergeInto(LibraryManager.library, {
    CallFGLInit: function (privateKeyPtr) {
        var privateKey = UTF8ToString(privateKeyPtr);        
        if (FGL && typeof FGL.init === "function") {
            FGL.init(privateKey);            
            SendMessage('FGLWebSDK', 'OnInitComplete');
        } else {
            console.error("FGL.init is not defined!");
        }
    },

    CallFGLRequest: function (adTypePtr) {
        var adType = UTF8ToString(adTypePtr);
        if (typeof FGL !== "undefined" && typeof FGL.Ads !== "undefined" && typeof FGL.Ads.request === "function") {
            FGL.Ads.request(adType)            
                .then(function (status) {                   
                    SendMessage('FGLWebSDK', 'AdComplete', status);
                })
                .catch(function (error) {
                    SendMessage('FGLWebSDK', 'AdError', error);                    
                });
        } else {
            console.error("FGL.Ads.request function not found!");
        }
    }
});
Step 2: Create the FGLWebSDK script

Create a folder in your project called "FGLWebSDK"

Create a new file called FGLWebSDK.cs in this new folder

Add the following code:

<code>
using System;
using System.Runtime.InteropServices;
using UnityEngine;

namespace FGL {


        public class FGLWebSDK : MonoBehaviour
        {
                private static FGLWebSDK _sdkSingleton;

                [DllImport("__Internal")]
                private static extern void CallFGLInit(string privateKey);

                [DllImport("__Internal")]
                private static extern void CallFGLRequest(string adType);

                public static void InitFGL(string privateKey)
                {
                        CheckSingleton();

                        Debug.Log("Calling InitFGL");
                        #if UNITY_WEBGL && !UNITY_EDITOR
                                CallFGLInit(privateKey);
                        #else
                                Debug.Log($"FGLWebSDK:: FGL Init called (non-WebGL environment) with privateKey: {privateKey}");
                        #endif
                }

                public static void RequestFGLAd(string adType,  Action<String> adError, Action<String> adFinished)
                {
                        CheckSingleton();

                        _sdkSingleton.errorCallback = adError;
                        _sdkSingleton.completeCallback = adFinished;

                        #if UNITY_WEBGL && !UNITY_EDITOR
                                CallFGLRequest(adType);
                                AudioListener.pause = true;
                        #else
                                Debug.Log($"FGLWebSDK:: FGL Request called (non-WebGL environment) with adType: {adType}");
                        #endif
                }
        
                
                
                private static void CheckSingleton()
                {
                        if (_sdkSingleton != null)
                        {
                                return;
                        }

                        var go = new GameObject();
                        _sdkSingleton = go.AddComponent<FGLWebSDK>();
                        
                        DontDestroyOnLoad(go);
                        go.name = "FGLWebSDK";
                }

                public Action<String> errorCallback;
                public Action<String> completeCallback;
                
                public void OnInitComplete() {
                        Debug.Log("FGLWebSDK:: OnInitComplete");
                }

                public void AdComplete(string status) {
                        Debug.Log("FGLWebSDK:: AdComplete - " + status);
                        AudioListener.pause = false;
                        if (completeCallback != null) {
                                completeCallback(status);
                        } 
                }

                public void AdError(string error) {
                        Debug.Log("FGLWebSDK:: AdError - " + error);
                        AudioListener.pause = false;
                        if (errorCallback != null) {
                                errorCallback(error);
                        } 
                }

                public void OnApplicationPause(bool pause)
                {
                            Debug.Log("FGLWebSDK:: OnApplicationPause - " + pause);
                        if (pause) {
                                AudioListener.pause = true;
                        } else {
                                AudioListener.pause = false;
                        }
                }
        }
}

How It Works

Godot (GDScript)

<code>
extends Node

var _sdk_initialized_callback
var _midgame_ad_result
var _rewarded_ad_result
var _sdk_initialized:bool = false
var _gd_midgame_callback:Callable
var _gd_rw_callback:Callable

# Godot GDScript Code
func initialize_sdk(private_key: String) -> void:
	# Check if the SDK is loaded		
	var is_sdk_loaded = JavaScriptBridge.eval("typeof FGL !== 'undefined'")
	var window = JavaScriptBridge.get_interface("window")

	if is_sdk_loaded:
		print("FGL SDK Detected.")
		_sdk_initialized_callback = JavaScriptBridge.create_callback(OnSDKInitialized)
		_midgame_ad_result = JavaScriptBridge.create_callback(OnMidgameAdResult)
		_rewarded_ad_result = JavaScriptBridge.create_callback(OnRewardedAdResult)
		window.OnSDKInitialized = _sdk_initialized_callback
		window.OnMidgameAdResult = _midgame_ad_result
		window.OnRewardedAdResult = _rewarded_ad_result
				 
		var init_code = """
			FGL.init('%s')
				.then(result => {
					if (result.success) {
						OnSDKInitialized('success');
					} else {
						OnSDKInitialized('failed');
					}
				})
				.catch(error => {
					OnSDKInitialized('error');
				});
	 """ % private_key
		JavaScriptBridge.eval(init_code)
		#setup ad requesting code
		var request_ad_js:String = """window.requestAd = async function(type) {
		try {
		let status = await FGL.Ads.request(type);
		let callback = (type.toLowerCase()==='midgame') ? window.OnMidgameAdResult : window.OnRewardedAdResult;
		console.log(`Ad load status: ${status}`);
		callback(status);
	} catch (e) {
		console.log("Error while loading ad: " + e);
		callback('failed');
	}
}"""
		JavaScriptBridge.eval(request_ad_js)
	else:
		print("FGL SDK is not loaded.")

func OnSDKInitialized(result:Array) -> void:
	if result[0] == "success":
		_sdk_initialized = true
		print("FGL SDK initialized successfully!")
	else:
		_sdk_initialized = false
		print("FGL SDK initialization failed: " + result[0])

LibGDX (Java)

<code>
// LibGDX Java Code
public void initializeSDK(String privateKey) {
    // Check if the SDK is loaded
    String checkSDKCode = "typeof FGL !== 'undefined'";
    boolean isSDKLoaded = (boolean) Gdx.app.getNet().evalJavaScript(checkSDKCode);

    if (isSDKLoaded) {
        // Initialize the SDK
        String initCode = String.format(
            "FGL.init('%s')" +
            ".then(result => {" +
                "if (result.success) {" +
                    "window.libgdxInstance.postMessage('OnSDKInitialized', 'success');" +
                "} else {" +
                    "window.libgdxInstance.postMessage('OnSDKInitialized', 'failed');" +
                "}" +
            "})" +
            ".catch(error => {" +
                "window.libgdxInstance.postMessage('OnSDKInitialized', 'error');" +
            "});",
            privateKey
        );
        Gdx.app.getNet().evalJavaScript(initCode);
    } else {
        Gdx.app.error("FGL SDK", "FGL SDK is not loaded.");
    }
}

// Callback method to handle initialization result
public void OnSDKInitialized(String result) {
    if (result.equals("success")) {
        Gdx.app.log("FGL SDK", "Initialized successfully!");
    } else {
        Gdx.app.error("FGL SDK", "Initialization failed: " + result);
    }
}

3. Requesting Ads

Once the SDK is initialized, you can request ads using the FGL.Ads.request() method. This method takes an ad type as a parameter (e.g., 'midgame', 'rewards') and returns a status string indicating the outcome of the ad request.

3.1 Handling Ad Request Status

The FGL.Ads.request() method returns one of the following status strings:

You should handle each status appropriately in your game logic. Below is an example of how to handle the status:

<code>
async function requestAd(type) {
    try {
        let status = await FGL.Ads.request(type);
        console.log(`Ad load status: ${status}`);
        switch (status) {
            case "success":
                // Reward the player here
                console.log("Ad was successfully shown. Reward the player.");
                break;
            case "failed":
                // Ad failed to load
                console.log("Ad failed to load. Handle this gracefully (e.g., retry or skip).");
                break;
            case "blocked":
                // Ad was blocked
                console.log("Ad was blocked by the user's browser or ad-blocker.");
                break;
        }
    } catch (e) {
        console.log("Error while loading ad: " + e);
    }
}

What Each Status Means and How to Handle It

3.2 Framework-Specific Examples

Below are examples of how to request ads in different frameworks:

Unity (C#)

Change "rewards" to "midgame" to request a midgame ad instead.

<code>
// Unity C# Code
FGLWebSDK.RequestFGLAd("rewards", (error) =>         
{         
    Debug.Log("Rewarded Ad Error: " + error);
    
}, (status) =>
{            
    switch (status) {
        case "success":
            // Reward the player here
            Debug.Log("Ad was successfully shown. Reward the player.");
            GrantReward();
            break;
        case "failed":
            // Ad failed to load
            Debug.Log("Ad failed to load. Handle this gracefully.");
            RetryAdRequest();
            break;
        case "blocked":
            // Ad was blocked
            Debug.Log("Ad was blocked by the user's browser or ad-blocker.");
            ShowMessage("Ads are blocked. Please disable your ad-blocker to continue.");
            break;
    }
});

Godot (GDScript)

<code>
# rewardedCB should be a func that takes 1 parameter (String) which is the result (success,failure,blocked)
func requestRewardedAd(rewardedCB:Callable) -> bool:
    if not _sdk_initialized: return false
    _gd_rw_callback = rewardedCB
    JavaScriptBridge.eval("window.requestAd('rewards')")
    return true

# midCB should be a func that takes 1 parameter (String) which is the result (success,failure,blocked)
func requestMidgameAd(midCB:Callable) -> bool:
    if not _sdk_initialized: return false
    _gd_midgame_callback = midCB
    JavaScriptBridge.eval("window.requestAd('midgame')")
    return true
    
func OnMidgameAdResult(result:Array):
    if not _sdk_initialized: return
    if _gd_midgame_callback != null:
        _gd_midgame_callback.call(result[0])
        
func OnRewardedAdResult(result:Array):
    if not _sdk_initialized: return
    if _gd_rw_callback != null:
        _gd_rw_callback.call(result[0])

LibGDX (Java)

Coming Soon

4. HTML5 Ads API and Diagnostics

HTML5 games should use FGL.Ads.requestDetailed() when they need to distinguish whether an ad was shown, a reward was earned, or a provider fallback was used. The older FGL.Ads.request() method remains available for integrations that only expect a "success" or "failed" status string.

4.1 Supported Ad Requests

const result = await FGL.Ads.requestDetailed("rewards", {
    placementName: "level-complete-reward",
    beforeAd: () => pauseGame(),
    afterAd: () => resumeGame()
});

if (result.rewardEarned) {
    grantReward();
}
Reward based on rewardEarned, not only legacyStatus. A request can complete normally without displaying an ad, and a dismissed rewarded ad must not grant the reward.

4.2 Detailed Result

requestDetailed() resolves to an object with the following fields:

{
    provider: "google",
    requestType: "rewards",
    placementType: "reward",
    placementName: "level-complete-reward",
    shown: true,
    rewardEarned: true,
    breakStatus: "viewed",
    audioManaged: true,
    legacyStatus: "success"
}

4.3 Provider Fallback

When Google H5 Games Ads is enabled, the SDK tries Google first. If a midgame or rewarded request is unavailable and fallback is enabled for the game, the SDK tries the current FGL provider. Preroll requests do not use the current provider fallback.

For rewarded requests, if neither provider can supply an ad and the player did not dismiss an offered reward, the SDK can return provider: "reward-fallback", breakStatus: "grantedWithoutAd", and rewardEarned: true so gameplay is not blocked by ad inventory.

4.4 Audio

The SDK automatically mutes tracked game audio while midgame and rewarded ads are active, then restores the previous state. Games can also report their sound setting to the ad provider:

FGL.Ads.setSoundEnabled(false); // Game sound is disabled
FGL.Ads.setSoundEnabled(true);  // Game sound is enabled

4.5 Console Diagnostics

Filter the browser console for [fgl-sdk][ads]. Every structured event contains an SDK version and a requestId that connects the full sequence for one ad request.

noAdPreloaded is an inventory result, not an SDK exception. If fallback is enabled, look for the following provider:fallback and final request:complete events. Console warnings from a third-party creative, including optional mraid.js loading warnings, do not by themselves mean the FGL request failed; use the final SDK result to decide what happened.

5. Debugging

The SDK includes a built-in debugger that logs important events and errors. To enable the debugger, evaluate the following JavaScript code from your framework:

<code>FGL.showDebugger = true;

This will display logs at the bottom of the screen, helping you troubleshoot issues during development.

6. Troubleshooting

If you encounter issues while using the SDK, check the following:

7. Conclusion

Congratulations! You have successfully integrated the FGL SDK into your game, regardless of the framework you are using. If you have any further questions or need assistance, please refer to the documentation or contact support.