| name | godot-platform-web |
| description | Expert blueprint for HTML5/web export on Compatibility (WebGL 2.0): JavaScriptBridge, localStorage wrapper, custom loading shells, COOP/COEP hosts, relative paths, beforeunload, visibility pause, and size optimization. WebGPU is out of scope. Keywords: web, HTML5, WebGL, Compatibility, JavaScriptBridge, localStorage, COOP, COEP, canvas, browser API. |
NEVER Do (Expert Web Rules)
Persistence & Storage
- NEVER use FileAccess alone for persistent web saves โ Prefer web_local_storage_wrapper.gd (
localStorage / IndexedDB via JavaScriptBridge).
- NEVER assume localStorage is permanent โ Implement cloud-save fallback for production.
Rendering & Logic
- NEVER use the Forward+ renderer for web โ Use Compatibility (WebGL 2.0).
- NEVER block the browser event loop โ Long sync work โ "Kill the Page." Use
await / threaded workers where available.
- NEVER ignore COOP/COEP โ Threads/
SharedArrayBuffer need cross-origin isolation.
UX & Security
- NEVER forget tab focus loss โ Pause audio on
visibilitychange.
- NEVER trigger Fullscreen/Mouse Lock without a click โ Must be inside a user gesture.
- NEVER use absolute paths in HTML shells โ Relative paths for subdirectory hosting.
Host checklist (procedure)
- HTTPS โ Required for many browser APIs (clipboard, some storage policies, secure contexts).
- COOP / COEP โ Serve isolation headers when enabling threads /
SharedArrayBuffer (see exporting-for-web docs).
- Relative shell paths โ Custom
index.html / PCK/WASM URLs must be relative so /game/ subpaths work.
beforeunload โ Wire web_navigation_guard.gd when unsaved progress exists.
- Compatibility renderer + texture compression โ Desktop browsers: S3TC/BPTC as appropriate; keep particle/draw budgets low.
Available Scripts
MANDATORY: For saves, load web_local_storage_wrapper.gd โ do not paste JavaScriptBridge.eval("localStorage.setItem...") string recipes.
Quota-safe localStorage via get_interface + JSON (no eval string interpolation).
Two-way JSโGD with create_callback (keep callback refs alive).
Canvas resize to browser viewport.
Suppress context menu / spacebar scroll defaults.
Remote PCK/resource fetch patterns.
Async clipboard via Navigator API.
Pause engine/audio on tab hide.
beforeunload unsaved-progress guard.
window.open with noopener.
VRAM/draw stats to JS console.
Also in scripts/
Expert WHY (critical)
CAUTION: Never persist via JavaScriptBridge.eval("localStorage.setItem('%s')" % data) โ injection/escaping bugs. Use web_local_storage_wrapper.gd.
- PWA updates โ
pwa_update_available โ pwa_update() when pwa_needs_update().
- WebGPU โ not a Godot 4.x web renderer; ship Compatibility (WebGL 2.0).
- JSON-RPC host page โ structured bidirectional bridge: web_json_rpc_bridge.gd.
Deep dive (load on demand)
PWA lifecycle, JSON-RPC bridge, localStorage anti-patterns, size knobs โ references/web-elite-patterns.md.
Loading shell (custom HTML)
<div id="loading-screen">
<div class="progress-bar"><div id="progress" style="width: 0%"></div></div>
<p id="status-text">Loading...</p>
</div>
<script>
const engine = new Engine(CONFIG);
engine.startGame({
onProgress: function(current, total) {
const percent = Math.floor((current / total) * 100);
document.getElementById('progress').style.width = percent + '%';
document.getElementById('status-text').innerText = `Loading ${percent}%`;
}
}).then(() => {
.().. = ;
});
Feature gate
if OS.has_feature("web"):
# Web-only: storage wrapper, visibility pause, navigation guard
pass
Size / perf knobs
[rendering]
textures/vram_compression/import_s3tc_bptc=true
textures/vram_compression/import_etc2_astc=true
- Target ~60 FPS mid-range browsers; cut particles, draw calls, huge textures.
- Keep download under a practical budget (~50MB) via exclude filters on docs/source.
PWA update hook
func _ready() -> void:
if OS.has_feature("web"):
JavaScriptBridge.pwa_update_available.connect(_on_pwa_update)
func _on_pwa_update() -> void:
if JavaScriptBridge.pwa_needs_update():
JavaScriptBridge.pwa_update()
Reference
Progressive disclosure: open Official Documentation links only when researching a specific API;
load Related Skills when routing work to a peer domain โ do not preload the whole lattice.
Official Documentation
Related Skills
Prerequisites
- godot-project-foundations โ Feature tags (
web), Compatibility renderer defaults, and display stretch settings every HTML5 export branch depends on.
- godot-input-handling โ InputEvent ownership before suppressing browser defaults (context menu, spacebar scroll) or remapping canvas focus.
- godot-save-load-systems โ Versioned save ownership and cloud-fallback hooks that
localStorage wrappers must not invent ad hoc.
Complements
Downstream / consumers
- godot-export-builds โ CI presets, artifact hosting, and size gates after browser APIs and Compatibility settings are locked in.
Master
- godot-master โ Library router and mirrored module entry for discovering this platform skill beside sibling domains.