Fixing a Chrome + Windows Game Bug
By Angus Cheng
A few weeks ago I added voice acting into Busty Barrister Barbara. It worked fine, until I tested out a Web build on my Windows PC. The audio sounded terrible, it sounded like it had gaps in it. Interestingly the bug only occured on Google Chrome for Windows.
Windows Chrome ❌
Windows Firefox ✅
MacOS Chrome ✅
MacOS Firefox ✅
MacOS Safari ✅
Sadly about 3.22 billion people use Google Chrome for Windows. It’s too large of a segment to ignore really.
Here’s a link to a build of the game with the bug: https://anguscheng.com/brabra/2024-02-06/
Change Audio Formats
The first thing I tried was changing audio formats from MP3 to OGG. That didn’t work. Then I tried WAV. Also did not work. Damn.
Look for Browser Errors
After that I snooped through the Chrome logs to see if anything came up.
› [Deprecation] The ScriptProcessorNode is deprecated.
Use AudioWorkletNode instead. (https://bit.ly/audio-worklet)
I’ll be honest. I clicked the link in the error message and my eyes glazed over. Reading it now, it does seem to describe the bug I faced. Anyway at the time I decided the message was a dead end and I moved on.
Raylib Discord
I searched through the history in Raylib’s discord. Tried a few things but couldn’t find anything. It seems like not many people are creating WASM games using Raylib.
I posted a question in there, but didn’t get an answer. Damn.
Found Bug in Raylib Example
It really seemed like a Raylib bug, but then I thought “What if it’s something wrong with my code?”. Then I had an idea “There must be a Raylib sound playing example, let’s see if it happens in one of those”.
It does. But only on Chrome for Windows.
Look a raudio.c
I had a quick look at the code, but it looked way too simple. Something else must be happening somewhere else.
Upgraded to Raylib 5
I realised I was still on Raylib 4.5, maybe this was fixed in Raylib 5?
brew install raylib
I then rebuilt Raylib for PLATFORM_WEB using these commands
emcc -c rcore.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2
emcc -c rshapes.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2
emcc -c rtextures.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2
emcc -c rtext.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2
emcc -c rmodels.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2
emcc -c utils.c -Os -Wall -DPLATFORM_WEB
emcc -c raudio.c -Os -Wall -DPLATFORM_WEB
emar rcs libraylib.a rcore.o rshapes.o rtextures.o rtext.o rmodels.o utils.o raudio.o
Then I looked at my build-wasm.sh script to see if I needed to change anything in there. I noticed the ASYNCIFY flag. Then I remembered people talking about how this flag causes the game to run slower. Maybe that’s why my web build runs at around 57 FPS instead of 60.
core_basic_window_web.c shows you how to run different rendering paths for Web and Desktop builds. Looked easy enough so I tried it out.
int main(void) {
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Busty Barrister Barbara");
InitAudioDevice();
SetTargetFPS(60);
GameData gameData = {0};
initialise(&gameData);
#if defined(PLATFORM_WEB)
emscripten_set_main_loop_arg(UpdateDrawFrame, &gameData, 0, 1);
#else
while (!WindowShouldClose() && !gameData.shouldClose) {
UpdateDrawFrame(&gameData);
}
#endif
CloseWindow();
return 0;
}
I made a build and then… messaged my Windows using friends to try it out.
My friend confirmed the bug appears in the February 6th build and is fixed in the February 7th build. Hell yeah!
Try it yourself
Build with bug
Build without bug
Bug fixed?
After reading Enter Audio Worklet it seems like I didn’t really fix this bug. It seems ScriptProcessorNode runs on the main thread, which I believe means if the game runs too slowly, it can eat up time that the audio processor needs to play sounds.
By removing the ASYNCIFY flag, I got my game the run faster, and this means ScriptProcessorNode is able to do it’s audio processing. Perhaps another way to ‘fix’ this bug would be to turn down the FPS from 60 to 30.
Perhaps the best way to deal with this is to help move miniaudio.h to AudioWorkletNodes.