Engine guide
Godot
Open-source engine with HTML5 export
Godot 4 exports to HTML5 via emscripten + a generated shell HTML. You integrate the SDK by editing that shell, then calling JS from GDScript through JavaScriptBridge.
1. Add the SDK to your exported shell
Open your Godot project's Export Template (Project → Export → HTML5 → Custom HTML Shell) and include the SDK before the Godot bootstrap:
<!-- somewhere before <script src="index.js"></script> -->
<script src="https://pixlland.com/sdk/v1/pixlland.js" defer></script>2. Autoload a PixllandSDK GDScript wrapper
Create autoload/pixlland.gd and add it as a global autoload:
extends Node
var _sdk: JavaScriptObject = null
func _ready() -> void:
if OS.has_feature("web"):
_sdk = JavaScriptBridge.get_interface("PixllandSDK")
func init() -> void:
if _sdk: _sdk.init()
func loading_progress(ratio: float) -> void:
if _sdk: _sdk.gameLoadingProgress(ratio)
func loading_finished() -> void:
if _sdk: _sdk.gameLoadingFinished()
func gameplay_start() -> void:
if _sdk: _sdk.gameplayStart()
func gameplay_stop() -> void:
if _sdk: _sdk.gameplayStop()
func happy_time(delta: float) -> void:
if _sdk: _sdk.happyTime(delta)
# Promises via JavaScriptBridge — await a one-shot callback.
func commercial_break() -> void:
if not _sdk: return
var done := [false]
var cb := JavaScriptBridge.create_callback(func(_args): done[0] = true)
_sdk.commercialBreak().then(cb)
while not done[0]:
await get_tree().create_timer(0.05).timeoutGodot 4's JavaScriptBridge is the successor to 3.x's JavaScript singleton — wrap it once so the rest of your game never touches it directly.
3. Call from your main scene
# Main.gd — autoload name = "Pixlland"
func _ready():
Pixlland.init()
Pixlland.loading_finished()
Pixlland.gameplay_start()
func _process(delta):
Pixlland.happy_time(delta)
func _on_player_died():
Pixlland.gameplay_stop()
await Pixlland.commercial_break()
get_tree().reload_current_scene()4. Save progress
# GDScript doesn't natively serialise dicts → JS; stringify first.
func save_progress(state: Dictionary) -> void:
if _sdk:
_sdk.data.set("progress", JSON.stringify(state))
func load_progress() -> Dictionary:
if not _sdk: return {}
var raw := await _sdk.data.get("progress")
return JSON.parse_string(raw) if raw else {}Common pitfalls
- Testing ads in the Godot editor. Ads only fire on the HTML5 build — the wrapper no-ops on native builds so your dev loop stays fast.
- Canvas size vs the SDK's ad overlay. The IMA overlay sits
position: fixedon top of Godot's canvas. Leave room — don't lock Godot to fullscreen during a commercial break.
Related reading: Vanilla HTML5 for the JS primitives used inside the bridge, SDK Basics for lifecycle semantics.
