Web target – progress and plans

Posted on


After the big engine release of 7.0 (coming really soon!), I’m dedicated to focus on adding the web target as a new engine platform.

The goal is simple: allow you to recompile more-or-less any application you wrote using Castle Game Engine (using TCastleWindow) to the web. So you can put your application on a website, as part of a normal HTML webpage, and users can play it instantly, without the need to download / install any native application or plugin.


  • We’re using FPC WebAssembly target. Huge thank you go to the whole FPC team of course for making it possible!

    Possibly there will be some additional “glue” bits done using pas2js (such “glue” is necessary as WebAssembly doesn’t otherwise get access to JavaScript APIs available in a web browser).

  • We will render using WebGL 1.0, with optional WebGL 2.0 features. This is very similar to current rendering on mobile, where we use OpenGL ES 2.0, with optional OpenGL ES 3.0 features.

  • For audio, we will add a new sound backend using WebAudio. This will be the default sound backend on the web (like the OpenAL is now the default backend on non-web platforms).

    It is also possible our FMOD sound backend will also be ported to web, as FMOD supports HTML5. This would make FMOD a truly cross-platform sound backend, working on every platform we support in CGE.

    I recently wrote more about WebAudio in the context of X3D 4.0. Supporting advanced X3D 4.0 audio nodes is not our priority, but since WebAudio will happen anyway, on the web… they will open this possibility. There is also LabSound that provides WebAudio-like API on non-web platforms, and in principle it could one day replace OpenAL, making web and non-web audio handling closer.

  • For data delivery, we know we’ll have to invent a simple format to carry our game data as one big binary blob. The simple plan is to just pack game data into zip.

  • For development purposes, likely we’ll add a “Run simple webserver on localhost” feature, to allow you easily run WebAssembly applications. This can be done using a number of things, I like most the idea of using fpWeb which can instantiate a standalone HTTP server in just a few lines of code.

What we have now:

  • Branch webassm_platformer_test in CGE contains a code that compiles (but it is not functional yet!) for WebAssembly. This means that CGE compiles, and also build tool supports a new OS/CPU. So you can enter any CGE project, and execute on command-line:

    castle-engine compile --os=wasi --cpu=wasm32
    # or
    castle-engine compile --os=wasi --cpu=wasm32 --mode=debug
  • We’ve encountered FPC issue #40229 (Wasm32 symbol xxx without index value error) but it is now happily fixed 🙂 Many thanks go to Nikolay Nikolov from FPC team for fixing, and Andrzej Kilijański for preparing a code to easily reproduce the issue.

  • Trung Le (Kagamma) has been doing lots of work with CGE + FPC WebAssembly. His fork contains a branch wasm32-wasi-port with lots of active work. I absolutely expect that we’ll merge it to CGE webassm_platformer_test at some point, and then to master branch 🙂

  • As noted by Trung Le (Kagamma), the important issue hanging on FPC now is #39547 (wasm32-wasi: Cannot create dynamic library). Go ahead and upvote it 🙂

  • File-size tests are promising. Compilation of examples/platformer, which practically uses 100% of CGE units, yields a binary platformer.wasm that has 16 MB. Gzipped it has 3.4 MB.

    The gzipped size is really what matters — both web browsers and servers support gzip-(de)compression on the fly, you can also just put ready-gzipped version on the server and tell the browser to just decompress. So in all practical cases, users will download 3.4 MB, not 16 MB.

    Note that above is for a release build. The debug build weights 51 MB, and gzipped 12 MB. How is the debug build actually useful on the web — I am not certain now 🙂

    We could also use Brotli, a newer compression method also commonly supported by web browsers and servers.

I want to thank everyone involved in this and let’s push forward! Web target is a really cool feature, from my talks I know it’s an important feature for many CGE users, and I feel we have it in our reach. Let’s keep coding and enjoy making games 🙂

Notable Replies

  1. This are really great news ! Wow !

    I think Web is super cool, because everybody is able to start your Game / App without to have it to install, or to download. In addition to this, it is platform independent ! Just great. Thanks for implementing this.

    I am not a big fan of the *.wasm, because of its file size! But you said: gzip / Brotli can compress it. So the browser read it on the fly. But the browser / frontend needs time to decompress it? Any numbers about decompr. time ? And does every browser support gzip (mobile, linux, playstation, etc)?

    Can you give an example, how to put a *.gzip into a adress, or html. Usually i always point to an html file. Like: https://test/my_test.html

    Can i use any compression-app like 7zip, to zip it into a *.gzip ?

  2. For the compression, really every browser in existence supports at least gzip. And 96% of them support Brotli. See

    The time to decompress is really negligible – I haven’t ever observed it being relevant at all. The decompression happens during downloading, and in practice decompression is likely faster than download, so you don’t really observe any delay. Pretty much everything you see on the Internet in your browser, including this very WWW page of our forum, is compressed – looking at WWW headers in Firefox console, I see my Firefox talks to our forum with Brotli.

    As for how to make the file compressed on the server: basically you can do nothing. Your www server can compress it on the fly. If you think it’s an overkill, remember this is already being done to most of data :slight_smile: See docs of Apache, Nginx how to configure what to compress. Alternatively you can tell the WWW browser it is already compressed, and then you can compress it yourself.

  3. Thanks for all the informations !

    I see my Firefox talks to our forum with Brotli.

    Cool…need to check this out.

    As for how to make the file compressed on the server: basically you can do nothing.

    You mean especially for the *.wasm file, i guess. Or even: png, js, css, etc ? Anyways, i need to investigate about gzip / brotli compressions.

  4. Everything.

    There are rules on each WWW server (Apache, Nginx…) to configure what to compress, so that e.g. PNG are no longer compressed on-the-fly with GZIP (which would generally make little gain as PNGs already employ a more specialized version of GZIP compression). But basically most things are compressed. Pretty much all HTML, CSS etc. you see now on any website is compressed :slight_smile: You can look at Firefox / Google Chrome Developer tools, see at headers sent – pretty much all browsers say “we accept gzip and brotli”, pretty much all www servers answer “cool, so this is your content in gzip / brotli”.

    In case of CGE, this would mean we:

    • compress *.wasm with gzip / brotli (and let browser decompress on-the-fly)
    • optionally compress even CGE data (which will already be .zip) using gzip / brotli. We’ll measure whether it makes sense, but we can do it.
  5. In case of CGE, this would mean we:

    • compress *.wasm with gzip / brotli (and let browser decompress on-the-fly)
    • optionally compress even CGE data (which will already be .zip) using gzip / brotli. We’ll measure whether it makes sense, but we can do it.

    Okay. This sounds good.

    I think i have too less knowledge about the backend processes at server-side. I just know, that if i compress files by my own via 7zip f.e. they are much smaller than just uploading them “raw” onto my server. Also compressed files by my own, the upload / download is faster than just “raw” files.

Continue the discussion at Castle Game Engine Forum


Avatar for sledge Avatar for michalis