The basic idea here is a small game-engine where you make "carts", in whatever language you like, which will run on native, libretro, or web.
Read the docs to find out more.
I'd like to support a lot of cart-languages. For these to be considered "complete", they should have a header that exposes all the functions/types in an ergonomic format, at least 1 example, a docker for building carts, and maybe a template-project.
compiled
- C (wasi-sdk)
- assemblyscript
- nelua
- rust
- nim
- go
- zig
- walt
- onyx
- grain
- D
- WAT
- odin
- c3
- Haxe (via HL/C - no try/catch, wasm has no exception-handling)
- Haskell (wasm32-wasi backend, tech preview - worth a prototype)
- Zen-C (transpiles to C - can likely reuse the wasi-sdk toolchain)
- Jik (also compiles to C - same idea)
interpreted
These include the interpretor in main.wasm. This is repetitive (like every js cart has a big quickjs main.wasm in it) but it makes them more host-agnostic, and reusable. It also means you can tune your interpretor around your game, if you really need to.
- javascript (ES5/6 via QuickJS)
- python (via RustPython)
- lua (via GopherLua)
- wren
- cyber (has an official
WASM WASIbuild target - worth a prototype)
probably will not support
These have a concrete technical reason they don't work today, found while investigating - not just "not gotten to yet". Full details in the add-cart-language skill.
- Kotlin/Wasm - close, but blocked by a real WAMR bug, not by policy. Its
wasm-wasitarget is standalone (no JS needed) and compiles to real wasm-GC structs, which null0's host now supports. But its stdlib relies on a wasm-GC array withanyrefelements, and WAMR's loader unconditionally rejects that ("Not support using anyref in array element type"). It also needs the-Xwasm-use-traps-instead-of-exceptionscompiler flag, since WAMR's fast interpreter can't be built with exception-handling support at all (a hard incompatibility, not a missing flag). Worth retrying if WAMR fixes the anyref-array gap upstream. - dart (dart2wasm) - its default output isn't standalone wasm: it imports
a
dart2wasmJS namespace and the JS-string-builtins proposal, both only servable by a real JS engine. Same problem as emscripten-style carts. - janet, and lisps/scripting languages implemented in C generally - they need setjmp/longjmp, which needs the wasm exception-handling proposal. See the Kotlin point above: WAMR's fast interpreter and exception-handling don't build together at all, so no toolchain flag gets around it.
- R (webR) - built with Emscripten and patched against R's source specifically to run inside an Emscripten JS runtime in a browser/Node. There's no standalone WASI build; same JS-glue problem as dart2wasm.
- julia - still experimental (type-stable code only, no exception handling, no multi-dimensional arrays or pointers), requires wasm-GC for heap allocation, and its docs frame it around exchanging objects with JavaScript rather than a standalone WASI import model. Worth another look once it's less narrow and less JS-shaped.
- Ada - GNAT-LLVM does have a
wasm32target, but the only real runtime built on it (AdaWebPack) is purpose-built for browser/Web API interop, not a standalone module with custom host imports. No evidence anyone ships a bare wasm32 GNAT runtime without that JS-facing layer. - spaceship/orbit - not a wasm target at all. It's a shell-replacement language that JIT-compiles to native code via LLVM for direct POSIX syscalls; no WebAssembly output exists or is planned.
- wyzer - no WebAssembly target exists. It's a choreographic distributed-systems language whose whole model is compiling one program into separate binaries per network node - that doesn't map onto a single cart wasm module even before a wasm backend would exist.
You can currently do all of these things yourself, or use a library for your language, but I think it would be cool to abstract them into the engine:
- GUI : microui. nuklear_console is also very nice for joystick-driven, but API is a bit more complicated. I may switch to this.
- tiled map/sprite
- physics
- FFT for audio/radio
- behind CLI flag: call native program, native files
See THANKS for acknowledgement and thanks for all the great help & code I received to make this.
See LICENSE for licensing information.