Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is awesome! Very nicely done. I hear a few problems with the audio emulation, (mostly clicks that shouldn't be there) but it's been a long while since I had my head wrapped around Gameboy emulation. I'm not sure I know what's going wrong exactly.

I love how Rust+WASM is an enabler for showing off applications like this which would traditionally be restricted to a desktop environment. Here's my own, an NES emulator, using wasm-bindgen for the translation but otherwise a similar setup:

https://rustico.reploid.cafe/?cartridge=patreon/tactus-v0.7-...

It's so cool to work on a bit of homebrew, then be able to share a link with someone and have it "just work" in their browser. No weird tools, no shady sites, just my game and their feedback.



> I hear a few problems with the audio emulation, (mostly clicks that shouldn't be there)

Almost anything WASM+Audio seems to do that in browsers today, unless you're really really careful about what you're doing and leverage multiple threads. I think the issue is mostly around single-thread contexts, where it has to switch between playing audio and other things.

I hit the very same issue myself with Bevy not too long time ago, and tracking this issue which has some further links if you wanna go down a rabbit-hole: https://github.com/bevyengine/bevy/issues/4078


I've had the same issue in my engine.

What I've found is that essentially WebAudio has such a terrible performance that the audio buffers need to be at minimum 100ms. And if you have a bad frame or any jank in your RAF is likely to glitch at least occasionally.

Compare this to when running natively 20ms audio buffers are fine.

I've settled on a design where I run all the audio graphs and audio decoding in a separate thread and then queue the audio buffers for the main JS thread to pick up and make the WebAudio calls. The same has to be done for the graphics (WebGL) as well. This can be major paradigm shift if the initial design has been done around doing stuff independently on the background. On the web.. no can do.

Bonus tip, if you're planning to use the OpenAL implementation that Emscripten provides my only advice is.. don't.


i combed through quite a few hobbyist gb emulators while writing mine and found audio to be pretty rarely finished or finished without issues. not sure if it's the same for NES


Audio is *surprisingly* tricky on both platforms. NES has DPCM, which cheerfully interrupts the CPU and causes untold issues with controller reading. Gameboy has envelopes that are semi-required with phase-resets, and a wave channel which you in theory cannot write new samples to, and developer hacks to work around both. Both systems have various hardware revisions that have subtly different behavior, and a handful of games that will break on that specific model. It's fun!


It's also more involved to verify operation. Graphics are easier to "measure" and compare. Sound is also much more timing-dependent, e.g. when timers are running on their own all the time. It's disconcerting when sound is slightly off in games.


Enthusiast noob question. What do you use for display / rendering / gui when doing emulators for wasm?


Wasm executes as its own VM, so you'll need some js glue to display something in the browser.

This means you can go both ways, either embed something like imgui in your wasm, or build a ui using html.


Or go full circle and use something like GameFace to render react in your app, in the browser!




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: