Skip to content

Port to Emscripten WebAssembly for Web Browser #136

@thiekus

Description

@thiekus

First of all, thank you for great effort makes recompileable NFS 2 to modern platforms, since I did play lot back in my childhood (and one of my first racing game I ever played, along with Road Rash Windows port). This is not a really issue post, since I took challenge to port NFS2SE into Emscripten WASM 32-bit, as you did mentions this able to compile NFS2SE.cpp as long is 32-bit little endian architecture, and I did it for whole week. Here's my result of porting efforts:

2026-01-06.15-31-37.online-video-cutter.com.1.mp4

Some notes:

  • Performance were good depending device configuration. It runs from slightly too fast in Intel Core i7 12700KF gives up to 200FPS on menu, to barely playable on my Surface Go 2 Intel m3 which averages to 10-15FPS.
  • Only OpenGL ES 2.0 backends supported as Emscripten have good emulation support for.
  • It needs SDL 2 manually compiled to support pthreads, since SDL2 pulled from Emscripten SDK one lacks of pthreads support.
  • Due to how NFS 2 game loop design have multiple main loop functions (common in older game), we can't simply use emscripten_set_main_loop_arg without much altering of original NFS2SE.cpp code. The great challenge not to able to compile NFS2SE.cpp but rather make it works without altering original code. So my approach is by run original game program on their separate thread (or in web term, worker), then in main thread I did implement small RPC named "Functions Runner" that run on main loop for invoke functions which only can run on main thread (OpenGL and creating audio context). Much like Emscripten ASYNCIFY feature but have more controls.
  • Due that workarounds and browser audioContext only can be created in main thread, performance on Chrome based browser were significantly drop than Firefox based because SDL audio seems tied to how long loop. In Chrome, loop for longer than 5ms did audio buffer underflow and makes popping. There's not problem in Firefox.
  • No game logic code were altered beacuse that efforts, though due to Emscripten (or WASM) have very strict data type checking at runtime, needs to 'shim' of the already wrapped functions. For example, function that originally void(int32_t,int32_t) declared as int32_t(int32_t,int32_t) in NFS2SE.cpp were acceptable on other environment, but gives warning at Emscripten compilation and throws error when that function will be executed.
  • Most of game features works, except network multiplayer which needs more works to able use TCP over WebSocket.
  • Assets were already loaded from zip files stored in web server. Though I'm planned to modularize so it can load as separate module and make loading mechanism from user-provided zip assets from their own, which is more preferable to avoid takedown if going to put online :) .

This would be benefited to another platforms that NFS 2 SE didn't as long as it has any Web Browser with WASM support, for example Apple Silicon Macs. I'll published my forks as soon as I have cleaned most of code mess I did, it would be mid or late of this month due to busy of making thesis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions