Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
thedivergentai avatar

Godot Platform Web

  • 165 installs
  • 454 repo stars
  • Updated July 28, 2026
  • thedivergentai/gd-agentic-skills

Use godot-platform-web for development tasks

About

godot-platform-web: A skill for development. This provides functionality for development workflows.

  • godot-platform-web

Godot Platform Web by the numbers

  • 165 all-time installs (skills.sh)
  • +18 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #2,345 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-platform-web

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs165
repo stars454
Last updatedJuly 28, 2026
Repositorythedivergentai/gd-agentic-skills

What it does

Use godot-platform-web for development tasks

Files

SKILL.mdMarkdownGitHub ↗

Platform: Web

Browser API integration, LocalStorage persistence, and size optimization define web deployment.

NEVER Do (Expert Web Rules)

Persistence & Storage

  • NEVER use FileAccess for persistent saves — Browsers sandbox the filesystem. Standard FileAccess to user:// is unreliable. Always use JavaScriptBridge for localStorage or IndexedDB.
  • NEVER assume localStorage is permanent — Browsers may purge local storage if space is low. Always implement a cloud-save fallback for production titles.

Rendering & Logic

  • NEVER use the Forward+ renderer — Forward+ requires Vulkan features that are unstable in browsers. Use the Compatibility (WebGL 2.0) renderer for consistent 60 FPS.
  • NEVER block the browser event loop — Long-running sync logic will cause the browser to prompt the user to "Kill the Page." Use await and background tasks.
  • NEVER ignore the COOP/COEP header requirement — Multi-threading and SharedArrayBuffer will fail on many hosts unless cross-origin isolation is configured server-side.

UX & Security

  • NEVER forget to handle tab focus loss — Audio playing in a hidden background tab is poor UX. Use visibilitychange to pause audio.
  • NEVER trigger Fullscreen/Mouse Lock without click — Browsers block security-sensitive requests unless they are inside a direct user interaction event.
  • NEVER use absolute paths in HTML shells — Use relative paths to ensure the game works when hosted in sub-directories.

---

Available Scripts

MANDATORY: Read the appropriate script before implementing the corresponding pattern.

web_javascript_bridge_callback.gd

Expert two-way JS-to-GD communication using create_callback.

web_local_storage_wrapper.gd

Robust localStorage handler with JSON serialization and quota error prevention.

web_responsive_canvas_adaptor.gd

Dynamic canvas resizing to match browser window dimensions via JS.

web_browser_input_guard.gd

Preventing browser default behaviors (Right-click menu, Spacebar scroll).

web_resource_lazy_loader.gd

Lazy loading of remote PCKs and resources using browser-fetch logic.

web_clipboard_interface.gd

Asynchronous clipboard (Copy/Paste) integration via the Navigator API.

web_visibility_auto_pause.gd

Visibility API integration to auto-pause engine and audio on tab hide.

web_navigation_guard.gd

Navigation guard using beforeunload to prevent closing on unsaved progress.

web_external_url_opener.gd

Expert URL opening using window.open with noopener security flags.

web_performance_profiler.gd

Browser performance tracking (VRAM, Draw calls) logged to JS console.

---

<!-- index.html custom loading -->
<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>

Browser Integration

# Check if running in browser
if OS.has_feature("web"):
    # Web-specific code
    JavaScriptBridge.eval("console.log('Running in browser')")

LocalStorage Save

func save_to_browser() -> void:
    if not OS.has_feature("web"):
        return
    
    var data := JSON.stringify(get_save_data())
    JavaScriptBridge.eval("localStorage.setItem('savegame', '%s')" % data)

func load_from_browser() -> Dictionary:
    if not OS.has_feature("web"):
        return {}
    
    var data_str := JavaScriptBridge.eval("localStorage.getItem('savegame')")
    if data_str:
        return JSON.parse_string(data_str)
    return {}

Size Optimization

# Minimize build size
[rendering]
textures/vram_compression/import_s3tc_bptc=false
textures/vram_compression/import_etc2_astc=true

# Exclude unnecessary exports
[export_preset]
exclude_filter="*.md,*.txt,docs/*"

Performance

  • Target 60 FPS on mid-range browsers
  • Limit godot-particles - WebGL has lower limits
  • Reduce draw calls
  • Avoid large textures

Best Practices

1. Loading Screen - Users expect feedback 2. File Size - Keep under 50MB 3. Mobile Web - Test on phones 4. HTTPS - Required for many APIs

1. PWA Update Lifecycle

Godot supports Progressive Web Apps (PWA) natively. Use the pwa_update_available signal to notify players of new versions and force a live reload using pwa_update().

func _ready() -> void:
    if OS.has_feature("web"):
        # Detect new PWA version waiting to be activated.
        JavaScriptBridge.pwa_update_available.connect(_on_pwa_update)

func _on_pwa_update() -> void:
    if JavaScriptBridge.pwa_needs_update():
        # Force the new version to install and reload all browser tabs.
        JavaScriptBridge.pwa_update()

2. WebGPU Beta-Feature Status

Godot 4.x targets WebGL 2.0 via the Compatibility renderer. While WebGPU is the future of web rendering, it is currently unsupported in Godot 4.x. To maximize performance, use the Compatibility renderer and enable VRAM texture compression (S3TC/BPTC for desktop browsers).

3. JSON-RPC Bridge (Browser Communication)

Create a structured, bidirectional communication bridge between Godot and the browser using the JSONRPC and JavaScriptBridge classes.

class_name WebRPCBridge extends Node
## Facilitates JSON-RPC communication between Godot and the Browser.

var _json_rpc: JSONRPC = JSONRPC.new()
var _js_callback: JavaScriptObject

func _ready() -> void:
    if not OS.has_feature("web"): return
        
    _json_rpc.set_method("update_score", _on_score_update)
    # Wrap GDScript callable for JS. Reference must be kept in class scope.
    _js_callback = JavaScriptBridge.create_callback(_on_js_message)
    
    # Inject into global window object.
    var window := JavaScriptBridge.get_interface("window")
    window.sendToGodot = _js_callback

func _on_js_message(args: Array) -> void:
    var json_payload: String = args[0]
    var parsed: Variant = JSON.parse_string(json_payload)
    if parsed is Dictionary:
        var response = _json_rpc.process_action(parsed)
        if response: _send_to_browser(JSON.stringify(response))

func _on_score_update(params: Variant) -> Variant:
    # Handle logic...
    return {"status": "ok"}

func _send_to_browser(json_str: String) -> void:
    var js := "if (window.onGodotMessage) { window.onGodotMessage('%s'); }" % json_str.json_escape()
    JavaScriptBridge.eval(js)

Reference

  • Related: godot-export-builds, godot-platform-mobile

Related

  • Master Skill: godot-master

Related skills

Backend & APIsbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.