bzt 4ec1f17b15 emscripten workaround not needed any more 1 年間 前
..
Makefile 4ec1f17b15 emscripten workaround not needed any more 1 年間 前
README.md 3abff4bf8b Video playback in emscripten port 2 年 前
tngp.html f529c11c28 Main menu, gamepad text input, credits, login, load game etc. etc. etc. 2 年 前

README.md

TirNanoG Player WebAssembly Port

This is just a technical feat, not a real platform. There's an insane and unreasoned hype about wasm, so we have created a port because we can, but while doing so we've decided that the wasm port is NOT SUPPORTED. If it works for you, that's great, if it doesn't, then do not open issues, those will most likely be ignored and closed with a "won't fix". You have been warned.

Running a compiled code in a browser might sound like a good idea at first, until you realize that it's unavoidably inherits all the limitations and restrictions of a browser tab, so in reality it just can't run real-life applications, by design. And on top of that, emscripten is a huge bugpile requiring massive amounts of JavaScript glue-code.

Known Issues

These simply cannot be fixed because of WebAssembly limitations and/or bugs:

  • only very simple TirNanoG games run (JavaScript sandbox has a painfully small memory, it isn't enough to load more complex games).
  • forget extensions, only single game.tng files (JavaScript has no means to list files in a local directory, so extensions cannot be detected).
  • forget multi-player games (JavaScript just doesn't have an UDP socket API needed for the TirNanoG MMORPG protocol).
  • forget saving and loading your game (JavaScript simply not allowed to access local files on your computer, and this is supposed to be a "security feature").
  • forget fullscreen (except press F11 to manually switch your entire browser to fullscreen before you load a game file).
  • laggy user input (everything goes through propagated DOM events until they reach the canvas element, then converted into emulated OS events, then converted into SDL events, so real-time response just not possible).
  • extremely poor IO performance (every IO hook must be implemented in native (non-bytecode) JavaScript libraries, furthermore needs converting the same data over and over again, promise buffer to ArrayBuffer, ArrayBuffer to Uint8Array, Uint8Array to wasm HEAP etc.).
  • extremely poor overall performance (no multithreading, everything is done in the main thread, plus adding a bytecode interpreter on top of an already slow, bloated browser application wasn't the best idea of the century performance-wise).
  • a browser alone is not enough, needs a static webserver too (ALL website components can be loaded from local files, even JavaScript libraries, but not WebAssembly. Loading a wasm file needs a working webserver. WTF?)
  • when you're finished playing the game, CLOSE YOUR BROWSER, because emscripten Asyncify is leaking memory badly and it is still running after the wasm program exited! The one and only way to stop it is closing your browser.

Notes for developers:

There's only a handful of libraries supported (and the most essential of all, the standard library libc, isn't one of them), and you cannot just compile any C/C++ source with emcc. Lots and lots of dirty hacks and armada of ifdef guards needed in the source code if it's more complex than a "Hello World" or a snake game (and let's face it, most libraries and applications are more complex than that).

Your build environment is going to be a mess too, because emscripten is using non-standard flags, so CC=emcc alone isn't enough as one would expect. The emconfigure and emmake helpers only work for basic use cases, but fail on most real-life library's Makefile. Luckily I have found an unofficial libtheora port which is VERY inefficitent, but at least compiles with emscripten. But video decoding still laggy as hell, because playing videos fluently would require a separate decoder thread, but (as it turns out) multithreading simply does not work in emscripten as of 2022 (emscripten's pthreads is implemented on top of SharedArrayBuffer, which is disabled on ALL modern browsers since 2020, and, in turn thanks to another browser bug and major security fuck up, cannot be enabled with http-equiv, you MUST have root access to the webserver and mess with its server config to add http headers... Something that a regular developer like me can't do on github / gitlab / sourceforge whatever codehosting site...)

And last, but not least, IT'S VERY POORLY DOCUMENTED. The documentation that exists assumes everything is working fine, but it's not! No trouble-shooting guide whatsoever! And you will face unspeakable horrors: uncatchable exceptions, incorrectly unwinded stacks, non-working command line flags, functions that can only be called from within the main loop otherwise they crash, console messages defying reality and attacking your sanity (like "there's no main_loop", but there is, what's more it is running!) etc., and you'll only be able to find small breadcrumbs, tiny shreads of information in emscripten's github issue comments about these, and that's only if your are very-very lucky...