Building a Web Game in C
By Angus Cheng
Christmas is coming up. When I used to work at a bank the entire month of December and a bit of January we were placed under “Change Freeze”. We weren’t allowed to deploy updates to our applications during this period. The thinking was:
- A lot of people are away over Christmas
- Application changes can lead to crashes
- People who know how to fix those crashes might be away
To prevent this they just stopped us from deploying updates. That meant December was a pretty relaxing time to be working at a bank, and it was also a good time to do big refactors, clean up TODOs or mess around with some new technology. So how about learning to code a game in C and build it out to WebAssmebly?
1. Install Raylib
Go here to get Raylib installed on your operating system. On Windows I used the installer which is available on itch.io and for MacOS I used Homebrew.
2. Create main.c
#include "raylib.h"
int main(void) {
InitWindow(512, 512, "Raylib WASM Example");
Texture2D texture = LoadTexture("resources/smile.png");
while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(BLACK);
DrawTexture(texture, 0, 0, WHITE);
EndDrawing();
}
UnloadTexture(texture);
CloseWindow();
return 0;
}
Create this file and place it in src/main.c
3. Copy this image
Copy this image and place it in src/resources/smile.png
4A. Build MacOS
gcc -Wall -fcolor-diagnostics -fansi-escape-codes -g src/main.c `pkg-config --libs --cflags raylib` -o out/main.out
4B. Build Windows
gcc src/main.c -lraylib -lopengl32 -lgdi32 -lwinmm -g -o out/main.exe
Run the Build
# Need to run from the src folder because the code wants the resources folder to be in the current working directory.
cd src
# MacOS
../out/main.out
# Windows
../out/main.exe
You should see this if you did it right. If not, hang your head in shame.
5. Download Emscripten
Now that we’re building successfully on Windows or Mac, we can get ready to build out to Web Assembly. I recommend you clone emsdk into the same directory where your game directory lives. You don’t have to but it’ll make running the build script we’re going to create easier.
# Get the emsdk repo
git clone https://github.com/emscripten-core/emsdk.git
# Enter that directory
cd emsdk
# Fetch the latest version of the emsdk (not needed the first time you clone)
git pull
# Download and install the latest SDK tools.
./emsdk install latest
# Make the "latest" SDK "active" for the current user. (writes .emscripten file)
./emsdk activate latest
# Activate PATH and other environment variables in the current terminal
source ./emsdk_env.sh
6. Create shell.html
Download this HTML file and place it in /shell.html
. It’s going to wrap around our web assembly game.
7. Create the build script
#!/bin/bash
set -euo pipefail
# Get EMSDK on the PATH
cd ../emsdk
source emsdk_env.sh
# Get into the /src folder
cd ../raylib-wasm-example
cd src
# Build to Web Assembly
emcc -o ../out/index.html \
main.c -Os -Wall /Users/anguscheng/workspace/raylib/src/libraylib.a \
-I. -I /usr/local/Cellar/raylib/4.5.0/include \
-L. -L /Users/anguscheng/workspace/raylib/src \
-s USE_GLFW=3 \
-s ASYNCIFY \
--shell-file ../shell.html \
--preload-file resources \
-s TOTAL_STACK=64MB \
-s INITIAL_MEMORY=128MB \
-s ASSERTIONS \
-DPLATFORM_WEB
# Get into /out
cd ../out
# Run the game
emrun index.html
Copy this file to /build-wasm.sh
you’ll have to change the -I and -L paths.
If it worked a browser should open up and show this page.
Github Repository
All source files are available here.
References
- https://www.youtube.com/watch?v=j6akryezlzc
- https://github.com/raysan5/raylib/wiki/Working-for-Web-(HTML5)
- https://emscripten.org/docs/getting_started/downloads.html