Publishing Web Exports from Godot 4
As of October 2023, there are two primary technical challenges when publishing web-exported projects using Godot 4, assuming that the end-user has an up-to-date, modern browser:
- Game files necessitate specific HTTP headers in server responses to execute properly.
- Due to a bug in the macOS versions of Firefox and Chrome, the game crashes during the loading on these browsers.
(You can test my current implementation for the things discussed on this article here).
1. Configuring the Web Server
Headers for Enabling SharedArrayBuffer
Firstly, concerning server configurations, Godot 4 operates exclusively in a multi-threaded mode, unlike Godot 3. Consequently, its web exports require the SharedArrayBuffer
feature in browsers. To comply with browser requirements, the webpage must be served over an HTTPS connection with the following headers:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Optimizing Download Times
Although not mandatory, optimizing download times for the engine and game files enhances user experience. One approach is to gzip the payload. For instance, using gzip can yield up to a 3.9x reduction in the engine .wasm
file. That file usual 29MB shrinks down to a 7.44MB download.
The .wasm
file, which holds the engine code, should be served with the application/wasm
MIME type and the .pck
file, which holds the game script and resources, should be served with the application/octet-stream
MIME type. Both MIME types can then be configured to be gzipped on the server.
As an additional optimization, caching and reusing the engine’s .wasm
file across multiple games on a website can further reduce load times.
2. MacOS Browser Bugs
On macOS, both Firefox and Chrome exhibit a bug that hinders the game’s loading process. Detailed technical insights into this issue are available here. As Safari is not plagued by this bug and comes pre-installed on macOS, redirecting macOS users to this browser serves as a viable workaround.
To implement this, JavaScript can be used for user-agent parsing to identify the user’s operating system and browser. One method is:
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
var isMac = navigator.userAgent.indexOf('Mac') > -1;
if (isMac && !isSafari) {
//...
}
Notably, pre-configured hosting services like itch.io do not consistently implement the required server configurations outlined above. Additionally, most web game hosting services do not adequately address transient issues like the macOS browser bugs.
In my experience, managing the hosting environment for your projects provides more control over these variables.