Live data from Hacker News

Ported my C game to WASM, here's every bug that I hit

ernesernesto.github.io

71–80 of 116 posts

Re: Ported my C game to WASM, here's every bug that I hit

#71
post #69
post #35

Earlier quoted context omitted.

> WASI still leaves something to be desired. Why can't I have raw sockets and file access and stuff, in a POSIX-like way? FWIW, that's exactly what they shipped first, with WASI preview 1 (wasip1). You can still use this today, and all runtimes with any level of WASI support will be able to run it.

Wasip1 did not specify sockets. Some implementations have made non-standard additions to add them, but sockets were not added to the standard until wasip2.

Sockets are officially specified in wasip1: https://wasi.dev/releases/wasi-p1

Notably, listen and connect are missing. But sockets themselves were in there.

Re: Ported my C game to WASM, here's every bug that I hit

#72

I just finished a similar project for fun and education. It was a 20-year-old codebase from my old game in win32 and DirectX 9. I first ported it to native and also switched to bgfx for rendering. This was the bulk of the work - converting all of the old DirectX fixed function pipeline code to shaders. Luckily all modern shaders can simulate all of the old fixed-function DX pipeline features with little effort. Inclu…

> I had no idea WASM is 32bit until I read your article!

WASM(32) is a hybrid 32/64 bit architecture. The address range (and thus pointer size) is 32 bits, but it has native 64-bit integers. E.g. it's similar to the Linux x32 ABI.

There is also a 'true' 64-bit wasm, but that's still too recent to be used in real-world code:

https://caniuse.com/wf-wasm-memory64

(but wasm64 doesn't really make sense unless you really need an address space greater than 32 bits, because the downside is slower performance)

Re: Ported my C game to WASM, here's every bug that I hit

#73
post #15

I love how WASM is the thing that finally blurred the line between Web and Native programming, formely two realms isolated from each other for a long time. This both develops better awareness of how the code is executed by the hardware, which JavaScript devs often lack, and also brings skilled folks from the Native platforms who seem to be not so against WASM as they were against JavaScript (and all other parts of th…

I wanted to love it. As someone who hasn't done any web stuff since I was a child, I thought it'd amazing for it to be "just another platform". I'm a bit disappointed though: * There's still no way to do DOM manipulation. So then it's tempting to just grab a canvas and draw everything yourself, which of course wreaks on things like accessibility. I'm no fan of the web, but at least it comes with a somewhat agreed-upo…

Using WASM to make cross-platform code run in browsers isn't any more weird/esoteric than targeting Android via the Android NDK. The least painful way is to do some things in the 'native' platform language (e.g. Javascript or Java/Kotlin). Emscripten's FFI features for calling out into Javascript code snippets (even JS snippets that are directly embedded in C/C++ source files) is actually really nice, much better than any other FFI solution I've seen so far (and light years ahead of anything offered by the Android NDK).

In the end the web is just another platform, but a platform that is quite a bit different from the UNIX/Windows duopoly we're used to.

Re: Ported my C game to WASM, here's every bug that I hit

#74

I love how WASM is the thing that finally blurred the line between Web and Native programming, formely two realms isolated from each other for a long time. This both develops better awareness of how the code is executed by the hardware, which JavaScript devs often lack, and also brings skilled folks from the Native platforms who seem to be not so against WASM as they were against JavaScript (and all other parts of th…

Wasm still doesn't let you make native user interfaces, the UI is in the web browser. You can put native UI components into a React Native or Electron app though.

> Wasm still doesn't let you make native user interfaces

That's currently only not possible because nobody wants to do the work to create something like wasi-gfx (https://wasi-gfx.dev/), but for native UI frameworks instead of 3D APIs.

The inconvenient truth is that even "native" cross-platform applications hardly ever go through the trouble to target the platform-native UI framework (and instead they go through non-native frameworks like Qt or a webview wrapper).

Re: Ported my C game to WASM, here's every bug that I hit

#75

Earlier quoted context omitted.

Because a web page shouldn’t use 4 GB of ram, and the win is that each pointer can be half the size (better for memory and cache). The real mistake is requiring pointer to be 64 bit when most programs don’t use it.

You sounds like the misattributed Bill Gates of 2026.

No? Most consumer desktops have 8 or 16 GB and phones less. You want to use more than half for a web page?

For reference 4 GB is 8x more than a ps3.

Re: Ported my C game to WASM, here's every bug that I hit

#76

Why is a relatively new technology like WASM being limited to 32-bit pointers? Why repeat the same mistake again? > Web is 32-bit. Your 64-bit structs will break. This was the root cause of most of my bugs. WASM is 32-bit address space, pointers are 4 bytes not 8.

Because 64-bit WASM can be quite a bit slower than 32-bit WASM:

https://spidermonkey.dev/blog/2025/01/15/is-memory64-actuall...

TL;DR: wasm64 requires explicit heap bounds checks, while in wasm32 the memory mapping hardware does it for free.

E.g. quote:

"The only reason to use Memory64 is if you actually need more than 4GB of memory.

Memory64 won’t make your code faster or more “modern”. 64-bit pointers in WebAssembly simply allow you to address more memory, at the cost of slower loads and stores."

Re: Ported my C game to WASM, here's every bug that I hit

#78
post #29

With regards to 1), do not write/read structs directly to/from files. Instead write a proper serializer/deserializer. Without it, you may encounter another breakage soon when a different compiler/compiler options insert different struct padding bytes, which will then once again make your data non-portable, and a maliciously crafted save file with no length/size field validation on the deserializer level can lead to a…

struct layout is well specified, it should be possible to avoid any padding issues by just aligning and by padding (with dummy members) correctly. The problem in practice is mostly integer representation (big-endian vs little-endian).

> struct layout is well specified

Technically that's not true at least for booleans and enums, the C standard doesn't define specific sizes for those (bools are commonly 1 byte though, but for enums at least MSVC likes to disagree with Clang and GCC).

Using a direct struct memory layout for persistency and then expecting it to work across compilers, CPUs and ABIs is almost guaranteed to cause problems.

Re: Ported my C game to WASM, here's every bug that I hit

#79

Earlier quoted context omitted.

struct layout is well specified, it should be possible to avoid any padding issues by just aligning and by padding (with dummy members) correctly. The problem in practice is mostly integer representation (big-endian vs little-endian).

If you modify or even just move fields around the struct that also changes the way they are serialized... You really need a serializer for this sort of thing because it can also include forwards compatibility of your data structures.

It's typical to only append fields when you do this.

Re: Ported my C game to WASM, here's every bug that I hit

#80

I just finished a similar project for fun and education. It was a 20-year-old codebase from my old game in win32 and DirectX 9. I first ported it to native and also switched to bgfx for rendering. This was the bulk of the work - converting all of the old DirectX fixed function pipeline code to shaders. Luckily all modern shaders can simulate all of the old fixed-function DX pipeline features with little effort. Inclu…

> I had no idea WASM is 32bit until I read your article! WASM(32) is a hybrid 32/64 bit architecture. The address range (and thus pointer size) is 32 bits, but it has native 64-bit integers. E.g. it's similar to the Linux x32 ABI. There is also a 'true' 64-bit wasm, but that's still too recent to be used in real-world code: https://caniuse.com/wf-wasm-memory64 (but wasm64 doesn't really make sense unless you really n…

> (but wasm64 doesn't really make sense unless you really need an address space greater than 32 bits, because the downside is slower performance)

Or unless you need to use integer types that depend on pointer size (such as size_t or usize), but your integers are too large to fit in 32 bits. That's a pretty common occurrence in bioinformatics. I've been waiting for years for Wasm to become usable, but it looks like Apple is still holding it back.

Post reply on HN