godotengine/godot
Web
Purpose
platform/web/ builds Godot for the browser. The engine compiles to WebAssembly via Emscripten; a JavaScript shim handles canvas creation, audio, file system access via the IndexedDB-backed Emscripten FS, networking via fetch / WebSocket / RTCPeerConnection, and input events through DOM events. The result is a .wasm blob and a small loader (.html / .js / .pck) that runs in any modern browser.
Layout
platform/web/
├── godot_web.cpp main() entry compiled by Emscripten
├── os_web.{cpp,h} OS_Web subclass
├── display_server_web.{cpp,h} Canvas + DOM event handling
├── audio_driver_web.{cpp,h} Web Audio API driver
├── http_client_web.{cpp,h} fetch()-based HTTP client
├── godot_js.h, godot_js_*.h C↔JS function tables (cdecl-ish)
├── library_godot_*.js JS-side helpers loaded by Emscripten
├── js/ TypeScript editor + engine glue (compiled to JS by emscripten linking)
│ ├── engine/ Engine.js bootstrap + project loader
│ └── editor/ Editor-specific JS (file picker, drag-and-drop)
├── api/ JavaScriptBridge: call JS from GDScript and vice versa
├── package.json npm + tsc setup for the JS sources
├── jsdoc2md/ JSDoc → Markdown for the public JS API
├── export/ Web exporter (HTML shell + WASM + PCK + service worker)
└── detect.py Emscripten toolchain detectionBuild
scons platform=web target=template_release
scons platform=web target=editor # web-based editor (experimental / for sandboxes)The build invokes emcc / em++ from Emscripten 3.1.62+. The output goes into bin/godot.web.template_release.wasm32.{wasm,js,html} (and matching debug variants).
Display server
DisplayServerWeb (display_server_web.cpp) attaches to an HTML canvas. It:
- Resizes the canvas to match
Viewportdimensions (with optional pixel ratio handling for HiDPI). - Routes DOM events (
mousedown,mousemove,wheel,keydown,pointerdown,pointercancel, …) intoInputEvents. - Supports
Pointer Lockfor mouse-look games. - Supports the Gamepad API for joypads.
- Exposes the Fullscreen API via
Window::set_mode(WINDOW_MODE_FULLSCREEN). - Implements clipboard via the async
navigator.clipboard.*API (with a fallback path throughdocument.execCommand). - Routes touch events (
touchstart/touchmove/touchend) for mobile browsers.
Rendering
Web uses the Compatibility renderer by default — it targets WebGL 2 via the drivers/gles3/ backend. WebGPU support is in progress in the engine but not yet the default.
Threaded rendering depends on the pthreads Emscripten flag (which requires COOP/COEP HTTP headers from the host). When threads are unavailable, the engine runs everything on the main browser thread.
Audio
audio_driver_web.cpp wraps the Web Audio API. The mixing happens in an AudioWorklet (or ScriptProcessorNode on legacy browsers) driven by the engine's mix loop.
File system
Emscripten provides a virtual file system that maps to:
- MEMFS for transient files.
- IDBFS (IndexedDB) for persistent user data.
OS_Web configures IDBFS as the user data dir and flushes writes asynchronously. The PCK ships as part of the page payload (or is fetched lazily via --main-pack).
JavaScript bridge
api/ exposes JavaScriptBridge to GDScript:
JavaScriptBridge.eval("alert('hi')")
var window = JavaScriptBridge.get_interface("window")
var location = window.location.href
JavaScriptBridge.create_callback(my_callback).bind_to_window("onresize")The bridge marshals arguments through Emscripten's value-typed arguments (numbers, strings, objects). Callbacks travel both directions.
Networking
- HTTP —
http_client_web.cppwrapsfetch(). Some headers are inaccessible due to browser CORS rules; the engine documents the limitations. - WebSocket — uses the browser's
WebSocket(inmodules/websocket/web_socket_peer_web.cpp), which is the only way to do binary network IO in the browser. - WebRTC — the
webrtcmodule providesWebRTCPeerConnectionover the browser API for peer-to-peer. - No raw TCP/UDP — browsers don't expose them. ENet is unavailable in web builds.
Export
export/export_plugin.cpp packages a project for the web:
- Generates an HTML "shell" (replaceable with a custom template).
- Bundles the WASM, JS loader, PCK, and (optionally) a Web App Manifest.
- Generates a service worker for offline + caching support.
- Configures COOP/COEP headers documentation if
threads=yesis selected.
The default shell is plain — most projects ship a customized HTML template.
Limitations
- File access outside the IDBFS sandbox requires user-initiated prompts (the File System Access API where supported).
- Some plugins / native modules (e.g., the Mono module) have limited or experimental web support.
- Audio latency is at the mercy of the browser's Web Audio scheduling.
- Memory is bounded by the WASM heap size; large projects must tune the build's
INITIAL_MEMORYandALLOW_MEMORY_GROWTHflags.
Key abstractions
| Abstraction | File | Role |
|---|---|---|
OS_Web |
platform/web/os_web.cpp |
OS subclass over Emscripten |
DisplayServerWeb |
platform/web/display_server_web.cpp |
Canvas + DOM input |
AudioDriverWeb |
platform/web/audio_driver_web.cpp |
Web Audio API |
HTTPClientWeb |
platform/web/http_client_web.cpp |
fetch()-based HTTP |
JavaScriptBridge |
platform/web/api/javascript_bridge.cpp |
GDScript ↔ JS |
EditorExportPlatformWeb |
platform/web/export/export_plugin.cpp |
Web exporter |
Entry points for modification
- Custom HTML shell → drop your file in the project and select it in the export preset.
- New JS API call → add an extern declaration in
godot_js_*.h, implement inlibrary_godot_*.js, and bind fromJavaScriptBridge. - WebGPU experimentation → look at
drivers/gles3/for the Compatibility-style backend; a future WebGPU driver would slot into the sameRendererCompositorinterface.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.