Native Client
Native Client or NaCl is the current technology used for virtualizing the game code in the Dæmon engine.
It replaced the Q3VM (Quake3 Virtual Machine) in the engine.
Unlike Q3VM for which the .qvm
binaries were limited to be produced with the old C supported by the proprietary LCC compiler, the .nexe
NaCl binaries can be compiled with Clang-based open source compilers supporting modern-enough C++ versions and allowing to reuse off-the-shelf C++ libraries that may even be shared between the engine and the game source code.
The Native Client documentation can be found on chrome.jscn.org/docs/native-client/welcome-to-native-client/.
Contents
Platforms
Linux | Windows | macOS | FreeBSD | |||||
---|---|---|---|---|---|---|---|---|
amd64 | i686 | arm64 | armhf | amd64 | i686 | amd64 | arm64 | amd64 |
✅️ native | ✅️ native | ☑️ through armhf compatibility |
✅️ native | ✅️ native | ✅️ native | ✅️ native | ☑️ through amd64 compatibility |
☑️ through Linux compatibility |
The NaCl loader (the virtual machine running the virtualized code) is available for three systems: Linux, Windows and macOS. The supported architectures differs per system:
- Linux:
- amd64,
- i686,
- armhf;
- Windows
- amd64,
- i686;
- macOS:
- amd64.
It is possible to run native engines with other platforms when there is a compatibility layer to run the NaCl loader:
- Linux:
- arm64, running the armhf NaCl loader through built-in Linux 32-bit compatibility;
- macOS:
- arm64, running the amd64 NaCl loader through Rosetta2 compatibility.
- FreeBSD:
- amd64, running the Linux NaCl loader through built-in Linuxulator compatibility.
The Linux i686 and armhf NaCl loaders may run on FreeBSD using Linuxulator but it is not tested.
NaCl upstream development has slowed down since the competing solution WebAssembly became the industry standard, so it is very unlikely support for new systems and architecture would be added. To overcome this problem, we would have to switch to WebAssembly (that unfortunately also lacks support for some platforms NaCl supports, like i686 or armhf).
NaCl also supports 32-bit MIPS on Linux but this architecture is not supported by the Dæmon engine and the Unvanquished game project.
Compilers
PNaCl
PNaCl is the current NaCl compiler we use to build the nexe game binaries. It is based on an old Clang 3.6 and does not support C++ above C++14. To overcome some of the related limitations we may switch to Saigo.
The PNaCl compilation workflow is to build a single .pexe
then to translate them to per-architecture .nexe
(amd64, i686, armhf) using a specific translator tool.
The PNaCl SDK consists on Python-based wrappers around Clang internals. It was initially using now-obsolete and hard-to-find Python2 but we ported it to Python3 to extend its lifespan.
The provided PNaCl SDK runs on Linux, Windows and macOS systems, on amd64 architectures.
While the .pexe
compiler itself runs on FreeBSD with the Linuxulator, the translator does not, meaning it's not possible to build .nexe
binaries on FreeBSD.
PNaCl supports C++ exception. There exist newer PNaCl SDKs (from chromium canary releases) that do not support exceptions and may not provide more what we already have with latest stable PNaCl.
Saigo
Saigo is a new NaCl compiler based on latest Clang and supporting latest C++ standards. It compiles directly to .nexe
.
Unlike PNaCl, Saigo do not provide released binaries, meaning a switch to Saigo requires a convenient way to provide it to contributors.
For now it has been successful to build an sgame.nexe
(server game binary) with Saigo and run it, so with more efforts it may be possible to also build the cgame.exe
(client game binary) as well and drop PNaCl.
Google provides some nightly Linux amd64 Saigo toolchain snapshots that aren't easy to get without some Google scripts.
The Saigo compiler and other related toolchain tools should build everywhere their upstream build, but only targeting the usual platforms, as the nacl_loader is basically the same: a more recent nacl_loader is also buildable but doesn't bring new platform supports.
The Saigo compiler itself isn't hard to build (same as Clang itself), what is more complex is to get the toolchain and the libc/libc++ to build.
Saigo may not support C++ exceptions as far as we know.
Moving to Saigo can be considered as a first step before migrating to WebAssembly, as it would allow us to migrate to a new C++ standard before migrating to WebAssembly, and the redesign of our CMake configuration for Saigo may help later when migrating to WebAssembly.
Here is a GitHub issue about the ongoing efforts at migrating to Saigo: