Godot and the WASM Tower of Duct Tape
If you’re here for a no-nonsense guide on how to optimize your Godot 4 HTML5 game for file size, click here to jump to it.
Recently, I became a contributor on
and started writing a little one-off game in Godot. Now, I had never used Godot before; all the game dev experiece I had was in Unity. I knew the game had to be playable on the web, and I sure as hell wasn’t in the mood to learn React right now, so I decided to use Godot because I could customize the logos on the loading screen. Of course, I ran into a bit of a problem:Long Load Times
While it’s not game-breaking it is experience-breaking. The original concept is to create a game that can capute the attention for at least 15 seconds, if players are forced to wait at least 10 seconds the first time they load the game up, they will probably just leave early.
Large .wasm
Files
The core
cause of the long loading size was the .wasm
file
containing the Godot engine. Weighing in at a whopping 42 MiBs! this is
what was responsible for the long loading times.
The reason this file is so large is because it includes everything required to run ANY Godot game, the default HTML5 export profile includes the entire Godot engine, including all the crap I don’t need like Every Single 3D Class.
For the absurdly simple game I was working on (basically just a UI with some animated sprites) I did not need to include any advanced features.
Solving the Problem
So, I look into optimizing loading times on HTML5 Godot games. I find
a bunch of very confusing resources first, including a very bad-faith online
service, but I finally locate the
official gude on how to optimize HTML5 exports for size. All the
earlier resources I found before only mentioned scons
, now
I can finally figure out what it is and why
it is used,
nevermind, that page is just vehemtly defending their use of
scons
as if the author was bullied for using it, alrighty
then.
I have no opinion on scons
but its the tool I have to
use. Of course, it’s probably one of the least irritating tools I need
to work with, and on that note time to describe my now eternal
against Emscripten.
So of course, the official guide says that you need Emscripten 3.1.39 or newer, so I pull down the latest stable Emscripten version. This fails. Okay, thats fine, I’ll go down the earliest known-good version of 3.1.39. It fails. a stray Github issue comment that indicates the earliest working version as 3.1.36. This finally works! Thank you random Github user, I forever curse the Emscripten developers for introducing regressions in what feels like every goddamn version release.
. What’s worse is that each attempt is taking at least 5 minutes on my system, usually longer. After some web sleuthing, I findNow, why did I call this the .wasm
Tower of Duct Tape?
As I was trying to get this to work, I kept finding Github issues and
discussions for the ENTIRE SUPPLY CHAIN behind Emscripten and Godot,
hence: “Tower of Duct Tape”.
Large software supply chains aren’t inherently bad, but when the link of the chain you’re interested in is the weakest, you’re going to have a bad time.
I’m proud to say that this entire procedure is responsible for about 25% of all my development time for this project at the time of writing. Anyway, on to the guide.
Guide: How to Optimize Godot 4 HTML5 for File Size
Install Emscripten
Despite what the documentation says, you actually need to install Emscripten 3.1.36. Versions after 3.1.36 are known to have regressions which prevent compiling.
The Emscripten
Install Documentation works for this version. But note: if you are
on Windows, use the correct script for your shell (i.e
emsdk.ps1
or emsdk.bat
)
Install SCons
The best way to install SCons is with pip
:
pip install scons
Remember: If you are installing this on windows, you must use a shell running as Administrator
Download Godot Engine
Using Git to download the Godot source code is ideal. Moreover, you
should only pull the version of Godot that you are using. You can look
at the Godot
tags to see the name of the version. This guide is for Godot 4.3 so
we will use 4.3-stable
:
git clone https://github.com/godotengine/godot.git -b 4.3-stable
Preparing Optimization Settings
To get the smallest file size, you want to disable all features that you aren’t using in your game. There are two ways to do this, and you should do both:
- Use Godot Build Options Generator
- Read through all the checkboxes and ensure the ones applicable to your use are selected
- If 3D is not used, disabling it will cut down on the size significantly
- Swapping to the text server fallback can save some space, but you need to pack your own font files
- Download the
custom.py
file and move it to your Godot source directory
- Read through all the checkboxes and ensure the ones applicable to your use are selected
- In the editor, go to Project > Tools > Engine Compilation Configuration Editor
- Click “Detect from Project”
- Verify that the profile is correct
- Click “Save As” and save the
.build
file somewhere accessible (in the Godot source directory works)
Acutally Building the Darn Thing
In the Godot source directory, run the command:
scons platform=web target=template_release threads=no build_profile=<path/to/build/profile>
Note: Be sure to replace <path/to/build/profile>
with the path to the .build file
generated in the previous
step. The compilation can take a very long time, when it’s dome your
template will be located at
bin/godot.web.template_release.wasm32.nothreads.zip
.
This zip file can be loaded in the “Release” field in the export screen. Be sure to uncheck “Export With Debug” when selecting the file location.
Testing It
The “Detect from Project” button can be a bit overzealous and remove things you do actually need. You may get error alerts in the browser itself, but most issues will simply result in missing Nodes. Here are some ways you can fix that:
- Open the Developer Console in your favorite browser and read through ALL the errors carefully to find out what is going wrong.
- Fix all the issues described, it should either tell you a Class name or a line in one of your scripts.
- Some of the class names listed in the browser console may not directly link to names you need to include (i.e.
FileAccess
will appear as"GDScriptNativeClass"
errors) - If this proves too difficult or time-consuming, you can remove the
build_profile=
part of thescons
command. It will result in larger file sizes, but ensure functionality. - Remember: this process can take a long time because it requires lots of tweaking