Godot Integration
This guide will walk you through integrating the GameLoop Funtico SDK into your Godot project. The SDK enables your game to interact with the Funtico platform for features like user authentication, leaderboards, and score saving.
Since Godot games exported for the web run in a browser environment, we’ll use JavaScript as a bridge between your GDScript code and the SDK. Don’t worry if you’re not familiar with JavaScript – we’ll provide all the code snippets you need.
Prerequisites
Section titled “Prerequisites”Step 1: Include the SDK Library
Section titled “Step 1: Include the SDK Library”Before your game can use the Funtico SDK, you need to include the SDK library in your HTML export. This is done by adding a script tag that loads the SDK from our Content Delivery Network (CDN).
You have two options for adding this script:
Option A: Through Export Settings (Recommended)
Section titled “Option A: Through Export Settings (Recommended)”- Open your project in Godot
- Go to Project → Export
- Select your HTML5 export preset
- Find the HTML → Head Include field
- Add the following script tag:
<script src="https://funtico-frontend-js-sdk.pages.dev/funtico-sdk.min.js"></script>Option B: Manual Addition
Section titled “Option B: Manual Addition”Alternatively, you can add the script tag directly to your export_presets.cfg file in the project root.
Step 2: Initialize the SDK
Section titled “Step 2: Initialize the SDK”Now we need to initialize the SDK when your game starts. This creates a connection between your game and the Funtico platform.
# Add this to your main game scene or a dedicated SDK manager scriptfunc _ready(): # Initialize the Funtico SDK var js_code = """ window.sdk = new FunticoSDK({ authClientId: 'your-client-id', // Replace with your actual client ID env: 'sandbox' // Use 'production' for live games }); """ JavaScriptBridge.eval(js_code)# Add this to your main game scene or a dedicated SDK manager scriptfunc _ready(): # Initialize the Funtico SDK var js_code = """ window.sdk = new FunticoSDK({ authClientId: 'your-client-id', // Replace with your actual client ID env: 'sandbox' // Use 'production' for live games }); """ JavaScript.eval(js_code)Step 3: Authenticate the User
Section titled “Step 3: Authenticate the User”Before you can use SDK functions like getting user info or saving scores, you need to authenticate the user. This redirects the user to Funtico’s login page, and after successful authentication, they are redirected back to your game.
# Call this when user clicks a "Login" or "Play" buttonfunc start_authentication(): var js_code = """ // Get the current page URL to redirect back to after login var callbackUrl = window.location.origin + window.location.pathname;
// Start the authentication flow window.sdk.signInWithFuntico(callbackUrl) .catch(function(error) { console.error('Authentication failed:', error); }); """ JavaScriptBridge.eval(js_code) # User will be redirected to Funtico login page # After successful login, they'll return to your game# Call this when user clicks a "Login" or "Play" buttonfunc start_authentication(): var js_code = """ // Get the current page URL to redirect back to after login var callbackUrl = window.location.origin + window.location.pathname;
// Start the authentication flow window.sdk.signInWithFuntico(callbackUrl) .catch(function(error) { console.error('Authentication failed:', error); }); """ JavaScript.eval(js_code) # User will be redirected to Funtico login page # After successful login, they'll return to your gameStep 4: Calling SDK Functions
Section titled “Step 4: Calling SDK Functions”The Funtico SDK uses asynchronous functions (also called Promises in JavaScript). This means when you call an SDK function, it doesn’t return a result immediately. Instead, it returns a Promise that will either:
- Resolve with the requested data (success)
- Reject with an error message (failure)
Implementation Differences Between Godot Versions
Section titled “Implementation Differences Between Godot Versions”Godot 3.x and 4.x handle JavaScript differently:
- Godot 4.x uses
JavaScriptBridgewithcreate_callback()andget_interface() - Godot 3.x uses
JavaScriptclass and requires a different approach for callbacks
Example: Getting User Information
Section titled “Example: Getting User Information”# Store callbacks as member variables to prevent garbage collectionvar _onsuccess_callbackvar _onerror_callback
func _ready(): # Initialize SDK first (see Step 2) # ...
# Create callbacks that JavaScript can call _onsuccess_callback = JavaScriptBridge.create_callback(_on_user_info_success) _onerror_callback = JavaScriptBridge.create_callback(_on_user_info_error)
# Get the SDK interface and call getUserInfo var sdk = JavaScriptBridge.get_interface("sdk") sdk.getUserInfo().then(_onsuccess_callback).catch(_onerror_callback)
func _on_user_info_success(data): # The SDK returns an array with user data as the first element var user_info = data[0] var username = user_info.username var user_id = str(user_info.user_id)
print("User logged in: ", username) print("User ID: ", user_id)
# Continue with your game logic # For example: show main menu, load user progress, etc.
func _on_user_info_error(error): print("Failed to get user info: ", error[0]) # Handle error - maybe show login screen or retry# Godot 3.x requires a different approach since it doesn't have create_callback
func _ready(): # Initialize SDK first (see Step 2) # ...
# In Godot 3.x, we need to use a different pattern # We'll store the result in a JavaScript variable and poll it var js_code = """ window.userInfoResult = null; window.userInfoError = null;
window.sdk.getUserInfo() .then(function(data) { window.userInfoResult = data; }) .catch(function(error) { window.userInfoError = error; }); """ JavaScript.eval(js_code)
# Start checking for the result _check_user_info_result()
func _check_user_info_result(): # Check if we have a result var result = JavaScript.eval("window.userInfoResult") var error = JavaScript.eval("window.userInfoError")
if result != null: # Success! Process the user data var username = result.username var user_id = str(result.user_id)
print("User logged in: ", username) print("User ID: ", user_id)
# Clean up JavaScript.eval("window.userInfoResult = null;")
# Continue with your game logic elif error != null: # Error occurred print("Failed to get user info: ", str(error))
# Clean up JavaScript.eval("window.userInfoError = null;")
# Handle error else: # Still waiting for response, check again in a moment yield(get_tree().create_timer(0.1), "timeout") _check_user_info_result()Step 5: Common SDK Functions
Section titled “Step 5: Common SDK Functions”Here are examples of commonly used SDK functions:
Save Score
Section titled “Save Score”var _onsuccess_callbackvar _onerror_callback
func submit_score(score: int): _onsuccess_callback = JavaScriptBridge.create_callback(_on_score_submitted) _onerror_callback = JavaScriptBridge.create_callback(_on_submit_error)
var sdk = JavaScriptBridge.get_interface("sdk") var promise = sdk.saveScore(score) promise.then(_onsuccess_callback).catch(_onerror_callback)
func _on_score_submitted(result): print("Score submitted successfully!")
func _on_submit_error(error): print("Failed to submit score: ", error[0])func submit_score(score: int): var js_code = """ window.submitResult = null; window.submitError = null;
window.sdk.saveScore(%d) .then(function(data) { window.submitResult = true; }) .catch(function(error) { window.submitError = error; }); """ % [score] JavaScript.eval(js_code)
_check_submit_result()
func _check_submit_result(): var result = JavaScript.eval("window.submitResult") var error = JavaScript.eval("window.submitError")
if result != null: print("Score submitted successfully!") JavaScript.eval("window.submitResult = null;") elif error != null: print("Failed to submit score: ", str(error)) JavaScript.eval("window.submitError = null;") else: yield(get_tree().create_timer(0.1), "timeout") _check_submit_result()Best Practices
Section titled “Best Practices”Troubleshooting
Section titled “Troubleshooting”Common Issues and Solutions
Section titled “Common Issues and Solutions”| Issue | Solution |
|---|---|
| ”sdk is not defined” | Ensure the SDK script is included in your HTML export and initialization code runs first |
| Callbacks never fire | In Godot 4.x, make sure callbacks are stored as member variables, not local variables |
| ”Cannot read property of null” | The SDK hasn’t been initialized yet. Check your initialization code |
| Functions work in one browser but not another | Clear browser cache and ensure you’re using the latest SDK version |