Building Web: WASM and template variants
Emscripten, threads, dynamic linking, ZIP contents and local diagnosis.
Choose the required output
This workflow builds WebAssembly templates from engine source. Exporting your game is separate: Web export. A template without game data is not a finished game.
Current C# limitation: Web is absent from the native .NET module's supported platforms, and the C# export plugin does not implement a Web target. module_mono_enabled=yes does not add browser publishing. The commands below do not establish C# game export.
Prepare tools
Use SCons 4.4 or later, Python 3.9 or later for the engine itself, and a working Emscripten SDK satisfying its own additional requirements. The platform/web/detect.py check rejects Emscripten below 6.0.1. This is a source-enforced lower bound rather than a promise that every newer release builds successfully.
Install and activate a chosen fixed version using emsdk. On Linux/macOS source emsdk_env.sh into the current shell; on Windows use the emsdk environment/emsdk_env.bat. Configuring emsdk. Check from that same terminal:
emcc --version
em++ --version
scons --version
python --versioncan_build only checks whether emcc exists in PATH. It does not validate the linker, all libraries, networking for initial SDK cache population or compilation. Do not change emsdk midway through one build batch.
Build debug and release
From Source, containing SConstruct, start with non-threaded variants:
scons platform=web target=template_debug threads=no
scons platform=web target=template_release threads=noArchitecture is wasm32. Expected ZIP names for this variant are bin/reckfell.web.template_debug.wasm32.nothreads.zip and bin/reckfell.web.template_release.wasm32.nothreads.zip. Additional build options can add suffixes; inspect actual outputs instead of renaming a similar old archive.
The ZIP includes matching .js, .wasm, audio worklets, HTML and shell/service-worker files. Do not transfer only the .wasm or combine .js and .wasm from different builds. Packaging uses shared staging directory bin/.web_zip: build configurations sequentially within one checkout and preserve completed ZIPs separately.
Set your ZIP as the game preset's corresponding custom debug/release template. When installing in a shared template directory account for threading/dynamic-link variants: renaming a file does not change its capabilities. Match the template to export settings and editor source/modules.
Threads, extensions and JavaScript
| Option | Effect |
|---|---|
threads=no | No pthread support; no SharedArrayBuffer requirement for engine threads. Does not remove browser requirements for WebGL, audio worklets and resource loading. |
threads=yes | Enables pthread/SharedArrayBuffer. Requires a secure context, cross-origin isolation, compatible resources and page policy. |
dlink_enabled=yes | Enables WebAssembly dynamic linking for native extensions; adds .dlink and a separate .side.wasm. Requires Web/Wasm library variants; desktop DLLs do not work. |
javascript_eval=no | Omits the conditional JS library and eval/interface C++ section. Does not disable JavaScript used by loading, graphics, input or audio; not a universal CSP configuration. |
proxy_to_pthread=yes | Separate mode running main application code in a worker. Requires threads; configuration disables it with threads=no or dlink. |
Threads default to enabled in common SCons configuration. Isolated threaded hosting typically needs Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp, or an appropriate equivalent. Inspect the actual page's crossOriginIsolated and SharedArrayBuffer availability rather than just server configuration. Iframes, external resources and service workers can affect the result. Cross-origin isolation requirements.
The current Web target disables RenderingDevice; plan for Compatibility/WebGL2 rather than desktop Forward+/Mobile. Initial WASM memory defaults to 32 MiB and stack to 5120 KiB; increasing memory does not fix missing target support or GPU memory exhaustion.
Web editor and local testing
target=editor builds the browser editor rather than a game template. It receives additional HTML/PWA files prefixed reckfell.editor, and its minimum initial memory is raised to 64 MiB. Do not use its ZIP in a game preset.
After extracting your output into a separate directory, use platform/web/serve.py for local testing. Its --root is resolved relative to platform/web, not the terminal's working directory; an absolute path removes ambiguity. Replace the example with your extracted build path:
python platform/web/serve.py --root "/absolute/path/web-build" --port 8060 --no-browserThe server adds COOP/COEP headers. It can listen beyond loopback and is intended for development rather than production hosting. Open the relevant HTML over HTTP and inspect Console/Network: files must not return 404 or HTML in place of WASM. Clear stale service-worker caches when replacing the file set. Loading HTML successfully does not establish level startup or rendering quality.
Review boundary: settings, ZIP composition and the minimum compiler gate were reviewed against source. Only isolated configuration/packaging function models were executed without a compiler or Web build output. Emscripten, SCons, browser runtime, threads, extensions and the Web editor were not run for this review; the engine was not changed.