Coding a Browser Game in C
By Angus Cheng
For the last few months I have been working on Bank Statement Converter and a Raylib game called “Customer Support Sim”. I coded “Customer Support Sim” using Raylib and Kotlin. Raylib is a really awesome game programming library and Kotlin is my favourite language. However sadly I’ve hit a bit of a wall with the game, I’m not really sure how to make it fun. I thought about releasing it ‘as is’, but I think it’s better just to abandon it.
While working on “Customer Support Sim” I have been a lot more interested in creating a game similar to Ace Attorney. I also have this theory that a lot more people will play a game if it is available on the web. App stores like Steam and Google Play are great for distribution but they still add in a bit of friction. If someone tells me to check out a game on Steam, I’ll make a mental note to try it later. If they give me a link to a browser game I’ll try it immediately.
Is my next game going to be written using a HTML5 game engine like Phaser? That would be logical, but no. Raylib allows you to compile your game to WebAssembly, however, you do need to code your game in C or C++.
Do Not Allocate
The last time I coded C was back in 2010. I worked at a company called Ingenico as firmware developer working on a software update. When I worked there we had a rule “library code is allowed to use malloc, application code is not allowed to”.
The devices we deployed to only had 2 megabytes of RAM. If you leaked memory, you could very easily fill up the RAM and cause the machine to hang. While I worked there we had a bug in production that caused a memory leak. This rule meant we had to set maximum sizes on the arrays we created. Instead of allocating a dynamic array we would think “Well they probably won’t have more than 10 items, so we’ll create a static array of size ten.”
For this next game I’m aiming to do zero heap allocations
List of IEvents
A big portion of this game is a bit like watching a Powerpoint presentation. If I were to code this in Kotlin I’d do something like this:
val events = listOf(
ShowText("You", "Hi nice to meet you"),
WaitForEnter(),
PlaySound("sfx.mp3"),
ShowText("Sandeep", "Nice to meet you too"),
WaitForEnter(),
)
Each of the elements in the list would conform to the IEvent interface. The game starts, sees a ShowText event. Renders the text into a text box. Then it sees a WaitForEnter element, and it waits for the player to press Enter. Quite a simple structure.
How do you do this in C though? C does not support interfaces. One idea I had was to create an enormous Event structure.
typedef struct Event {
ShowText showText;
WaitForEnter waitForEnter;
PlaySound playSound;
char* type;
}
That would probably work, but it’s not very nice code. Another option I thought of would be to encode the events as strings.
char *events[100];
events[0] = "SHOW_TEXT You Hi nice to meet you";
events[1] = "WAIT_FOR_ENTER";
events[2] = "PLAY_SOUND sfx.mp3";
events[3] = "SHOW_TEXT Sandeep Nice to meet you too";
events[4] = "WAIT_FOR_ENTER";
This would work, but then encoding all the event data would be very annoying. It just doesn’t seem right either. It did however lead me to the idea I’m going to do.
typedef struct Event {
char type[20];
int index;
}
ShowText showTextEvents[100];
WaitForEnter waitForEnterEvents[100];
PlaySound playSoundEvents[100];
Event events[200];
events[0] = (Event) { "SHOW_TEXT", 0 };
showTextEvents[0] = (ShowText) { "You", "Hi nice to meet you" }
...
It’s not super nice, but I think it’ll work and I’m happy to give it a go.
No header files
It’s been a while since I coded in C, but I do recall not enjoying writing header files. They seem redundant. I’m sure that modern IDEs take a bit of the pain away, but I couldn’t find an IDE that I enjoyed using. So I’ve been coding this game in Visual Studio Code. Initially I stuck all my code in main.c, but eventually it got a bit too long for that. I then thought “I’ve used C libraries that were distributed as single header files. What if I stick my code in header files and don’t bother writing the implementation files?”
So I stuck some min and max functions in a header file, and #included them in my main.c. Worked fine. I decided to ask Twitter what they thought of my header only plan.
Raysan, the main developer of Raylib does something very similar. If it’s good enough for him, it’s good enough for me. I renamed my .h files to .c files.
Reimplement engine
I want to have the same engine features as Ace Attorney, so my plan is to watch YouTube videos of the game and implement features as I see them. “Oh looks like the screen shaked at this point. I need to implement that as well”. Once I have enough I’ll start writing the story for the game. I’ve actually started already, but I’ve been in more of a coding mood this week so I started coding the engine.