godot-platform-web

v2026.09.24

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.

GitHub
安装命令
npx skhub add thedivergentai/godot-platform-web
Markdown
SKILL.md

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)

  1. HTTPS — Required for many browser APIs (clipboard, some storage policies, secure contexts).
  2. COOP / COEP — Serve isolation headers when enabling threads / SharedArrayBuffer (see exporting-for-web docs).
  3. Relative shell paths — Custom index.html / PCK/WASM URLs must be relative so /game/ subpaths work.
  4. beforeunload — Wire web_navigation_guard.gd when unsaved progress exists.
  5. 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.

web_local_storage_wrapper.gd

Quota-safe localStorage via get_interface + JSON (no eval string interpolation).

web_javascript_bridge_callback.gd

Two-way JS↔GD with create_callback (keep callback refs alive).

web_responsive_canvas_adaptor.gd

Canvas resize to browser viewport.

web_browser_input_guard.gd

Suppress context menu / spacebar scroll defaults.

web_resource_lazy_loader.gd

Remote PCK/resource fetch patterns.

web_clipboard_interface.gd

Async clipboard via Navigator API.

web_visibility_auto_pause.gd

Pause engine/audio on tab hide.

web_navigation_guard.gd

beforeunload unsaved-progress guard.

web_external_url_opener.gd

window.open with noopener.

web_performance_profiler.gd

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)

<!-- index.html custom loading — keep asset URLs relative -->
<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(() => {
    document.getElementById('loading-screen').style.display = 'none';
});
</script>

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.
发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

LGPL-3.0

源路径

skills/godot-platform-web

默认分支

main

最新提交

4c4d0ff

Tree SHA

4df5616