How to export your Unity game to WebGL for the browser
Switch your Unity project to the Web platform (File > Build Profiles > Web), turn on Brotli or Gzip compression in Player Settings > Publishing Settings, and build. naughty.games serves the compressed files with the right Content-Encoding header automatically, so you do not need Decompression Fallback unless you plan to host the same zip somewhere that cannot send that header. Test the build on a local web server, never by double-clicking index.html, then zip it with index.html at the top and upload it.
Last checked
What you need
- Unity 6.6 (6000.6) or a recent Unity 6.x release, with the WebGL Build Support module installed through Unity Hub.
- A project that already runs in the Editor. Unity does not add anything web-specific to your gameplay code; the work is in the build settings.
- Some spare time the first time you build with Brotli compression: it packs smaller than Gzip but takes longer to run.
Your build runs inside an iframe on naughty.games, behind the site's own age gate, so you do not need to add an age check inside the Unity project itself.
Export for the web
- Install WebGL Build Support. In Unity Hub, open your Editor version, click the gear icon, choose Add Modules, and install WebGL Build Support if it is missing.
- Switch platform to Web. Open File > Build Profiles, select or add the Web platform, and click Switch Platform.
- Set compression. Open Player Settings (the gear icon in Build Profiles) > Web > Publishing Settings. Set Compression Format to Brotli or Gzip. Leave Decompression Fallback off.
- Tune memory if your game targets phones. Still in Publishing Settings, set Initial Memory Size to roughly what your game actually uses, and turn on Memory Growth Mode (Linear is the more predictable option) instead of reserving a huge fixed heap up front.
- Build. Click Build, pick an output folder. Unity writes
index.html, aBuildfolder holding.loader.js,.framework.js,.wasmand.datafiles, and aTemplateDatafolder with the loading screen assets.
About compression on naughty.games
naughty.games hosts your build on its own subdomain through a Cloudflare Worker reading from storage. That Worker looks at each file's own name: a file ending in .br is served with Content-Encoding: br, and a file ending in .gz is served with Content-Encoding: gzip. That is exactly what a Unity build compressed with Decompression Fallback off expects, so Brotli or Gzip compression works correctly here as long as you upload the files Unity generated without renaming or re-compressing them.
If you would rather not think about server headers at all, or you plan to host the same zip somewhere else too, turning Decompression Fallback on is the safe, zero-configuration choice: Unity bundles a small JavaScript decompressor so the build works no matter what the server sends, at the cost of a bigger loader and a slower first load.
One more thing to leave off: WebGL multithreading. Threaded builds need SharedArrayBuffer, which only exists on a cross-origin isolated page, and naughty.games does not currently send the Cross-Origin-Embedder-Policy header that isolation requires. Export single-threaded, which is Unity's default.
Test it locally
Opening index.html straight from your file system will not work. Browsers block WebGL builds from fetching their own .wasm and .data files over a file:// URL, so the canvas either stays blank or gets stuck on the loading bar.
Serve the build folder over HTTP instead. From inside the folder, run:
python -m http.server 8000
Then open http://localhost:8000 in your browser and play through the build before you upload anything.
Zip it for upload
index.htmlmust sit at the top level of the zip. Zip the contents of the build folder, not the folder itself.- Stay under 250 MB unpacked and 2,000 files. A typical Unity WebGL build is a handful of files well inside that limit unless you bundled a lot of uncompressed video or voice audio.
- Strip anything you do not need: the optional
.symbols.jsondebug file (only useful if you are decoding crash reports), unused splash art if you swapped in your own loading screen, and any StreamingAssets you are not actually shipping.
Common problems
- Blank canvas or stuck loading bar. You opened the build over
file://instead of a server, or the relative paths to the Build folder got broken when you re-zipped it. Serve it over HTTP and check the folder structure matches what Unity generated. - The build fails to load only after upload, not locally. You likely renamed or manually recompressed one of the generated files. Upload the
Buildfolder exactly as Unity produced it so the file extensions (.br,.gz, or plain) match what your Player Settings say. - Out-of-memory crash on phones. iOS Safari enforces a much smaller WebGL heap than desktop browsers. Lower Initial Memory Size and turn on Memory Growth Mode instead of a large fixed heap.
- No sound until the player taps the screen. Mobile browsers block audio until a user gesture happens. This is expected browser behavior, not a bug in your build.
- Runs fine on your desktop, struggles on older phones. Phones have far less memory and GPU power than desktops, and a large share of naughty.games traffic plays on phones. Keep textures and audio compressed and test on a real mid-range phone before you publish.
Publish it
Once your build works from a local server, upload the zip (index.html at the top level, up to 250 MB unpacked and 2,000 files) to naughty.games, or give us an https URL if you would rather embed an existing build. Review usually takes about 2 working days, listing is free and non-exclusive, and any Patreon, Ko-fi, Steam or itch links inside your game earn you 100% of what they bring in. Head to /submit when you are ready.
Questions
- Which Unity version does this guide use?
- Unity 6.6 (6000.6), the current stable release with the Web platform under File > Build Profiles. Any recent Unity 6.x release works the same way.
- Should I use Brotli or Gzip compression?
- Brotli compresses smaller but takes longer to build. naughty.games serves both correctly, so pick Brotli unless your build machine is slow and you are iterating often.
- Do I need Decompression Fallback for naughty.games?
- No. naughty.games reads the .br or .gz suffix on each file you upload and sends the matching Content-Encoding header, which is exactly what a compressed Unity build expects. Turn Decompression Fallback on only if you host the same build somewhere that cannot set that header.
- Can I use a multithreaded WebGL build?
- Not usefully on naughty.games yet. Threaded builds need SharedArrayBuffer, which requires the page to be cross-origin isolated, and naughty.games does not currently send the Cross-Origin-Embedder-Policy header that isolation needs. Export single-threaded, which is the default.
- Will players keep their save data?
- Unity WebGL writes PlayerPrefs into the browser's storage, so saves stay on that browser and device but will not follow a player to a different device or browser.
Sources
Free hosting, real players on phone and desktop, and a stats console.