Home

Awesome

n64js

n64js is an n64 emulator written in (mostly) pure ES6 JavaScript. It runs many roms at full framerate.

Why?

Mostly for the challenge. I've spent ~25 years (on and off) working on N64 emulators and writing one in JavaScript gives me the opportunity to expand my comfort zone and learn something new. It's a good showcase for how powerful modern browsers have become.

How To Run

A hosted version is available on GitHub pages at https://hulkholden.github.io/n64js/.

Development

Install bun: https://bun.sh/.

Compile sources (pass --watch to automatically recompile on any change):

bun run build --watch

Run a local webserver in the root directory:

python3 -m http.server

Navigate to http://localhost:8000/.

If you want to run without installing bun, you can change the importmap in index.html to point at src/n64.js instead of build/n64.min.js.

Compatibility

Compatibility has improved a lot over the past few months.

As of 2023-09-23 95% of n64-systemtest tests now pass.

The areas where tests are failing are:

The floating point issues are largely edge cases with rounding values close to the numerical limits for 32 bit floats.

Beyond the things n64-systemtest covers, the main compatibility issues I'm aware of are:

Imprecise cycle counting affects some roms more than others. GoldenEye in particular seems to hang when LLE audio emulation is enabled on the RSP. I suspect this is due to the CPU running faster than it should be and causing the game to overflow audio buffers.

Graphics are rendered using high-level emulation and there are still a lot of TODOs. Many roms are playable but most have graphical issues of some kind.

Browser Compatibility

Performance

I've been testing on an Apple M2 Max and most roms run at full framerate most of the time. LLE audio emulation seems to be the biggest performance hit. To date I've mostly been focussed compatibility so there are likely a lot of improvements to be made here.

Implementation Status

TODOs

Here's some things I'd like to get around to:

History

n6js is derived from Daedalus, an emulator I started working on around 1999 and continued working on periodically for many years. Around 2012 I made a bet with @mmalex that I could write a port in JavaScript, and n64js was born!