For the third block of my programming course at Breda University of Applied Sciences, I had to remake Atari’s Original Gauntlet on the Raspberry Pi 4 Model B. I was provided a template created by one of the teachers, which used OpenGL to load in a model from a Wavefront Obj file (.obj) and spin it around. I messed around a bit and created a camera class with which I could fly around the scene but ultimately concluded that the template was a total mess. It had no wrappers, there were comments everywhere that were stating obvious things, unneeded variables, and all sorts of bad things. After 3 days of making sense of that template, I decided to scrap everything a start anew.
A good friend of mine found a nice EGL / X11 template for Linux, edited it a little bit for clarity, and gave it to me, thus I started creating everything needed from scratch (that same friend also wrote a nice input system which I also stole). Thanks to Cherno’s OpenGL Videos that I went through before the block started I had a good idea of what OpenGL code I needed and how to write nice wrappers for it. That was done relatively quickly.
Afterward, I transferred the Camera class and an edited down version of the Transform class, created a more reliable deltaTime with std::chrono, added ImGui (this blog post by one of our teachers helped me a lot), and by the second week, I had a better, cleaner template on which I could continue building my framework. I also added Phong Lighting with the help of Learn OpenGL by Joey De Vries (a vital resource for me in this project, btw). I also attempted to add model loading through assimp but that went about as well as the GIF below shows :))
Of course, I eventually fixed it but I find this gif to be more entertaining.
By the start of the third week, I had gotten completely tired of the Raspberry Pi after I had to reinstall its OS 4 times in one day. I knew that it was a huge time sink and I wanted to get rid of it. I decided that the best way to fix this was to get rid of it completely. I asked around and got the help of a few higher year students and they gave me some great advice about project structure and how to do what I want. By the end of week 3, I had my project running on both Windows and Linux (Raspberry Pi). The Windows version used GLFW and GLEW whilst the Linux one EGL and GLES3.
I found graphics to be fun, so I continued doing that throughout the next fourth week. I added (in this order):
Afterward, I decided to do some work on one of the requirements for the project on which I had made 0 progress. Physics. We were strongly encouraged to use PyBullet for our physics and so that’s what I did. The documentation for it was pretty bad and I had to rely on the trial and error of me and my classmates and the demo of that framework. I got a lot of help from various people setting it up and making it work as I want to. The most tricky bit about it was the connection between the transformation/rendering part and the rigid-body physics component part.
Here I want to talk a bit about design. Because I’m relatively new to writing C++ code I opted for copying an already existing engine’s design for the GameObject class. I decided to steal Unity’s. If you look into my GameObject class you will see a Model (meshes, textures), Transform (world values, rotation, scale), and a Physics (rigid-body / collider), component.
From this point, I had everything that I needed to start working on the game and I had three weeks left. I did a lot of abstraction so I could recreate each object and its components. Now I could easily create objects, modify each object, create as many lights and change all of their values freely. ImGui was extremely helpful to this extent.
Note that the textures in this GIF were procedurally generated with Perlin Noise.
Finally, the only thing that I needed to add was some sort of gameplay, UI, game state manager, allocation and deallocation of resources, and level loading. I had 1 week for all of that work but I managed to get it to some sort of completed state. I wish I could’ve spent more time tweaking with values to make things more fun but I am still very happy with the result considering the huge time constraint that I had.
At the end of the project, I submitted something that looked very similar to this. On the Raspberry Pi the game runs between 25 – 35 FPS while on Windows it’s about 95 FPS. I have a lot of ideas where I could optimize it further, one of them being by instancing the level drawing but I didn’t have the time.
There is still a lot to see so I would recommend downloading, building, and running my project. Keep in mind that there is a big difference between Debug and Release as Debug allows full control over everything while the game is running thanks to ImGui. I would also love to hear any feedback on the code side of things if that’s your thing :).
A few final things to add about this block. It was a lot of hard work but overall I enjoyed it. That was most likely because I decided to come back to developing on Windows since building the project on the Pi and running it took around 2 minutes. Other than that I improved my project structure a great ton, got to work with a physics engine, and deal with 3rd party code.
A bit of feedback I could give to the structure of the block is that we were expected to do things that weren’t needed if we stuck to the project brief 100%. A big part of the criteria for our grades was determined by a lot of complex tasks which just aren’t viable in a game as old/simple as Atari’s Gauntlet from 1985. There are better solutions that would’ve given us more performance considering the hardware that we’re working on and I would’ve liked a bit more flexibility in that part.
As frustrating as it was working on the Raspberry Pi was a valuable experience that I wouldn’t trade for the world. I got to experience most of the Linux quirks and features that I’ve been hearing so much about and also take a few steps into cross-platform development. I am satisfied with this block, I just wish I had more time to polish everything a tiny bit more.
Thanks for reading my post.