Time/Merge - A student custom engine project
An introduction to the Game Engine I wrote in C and how I used it to build a game in C++
Welcome.
This is a summary of the story behind my final school project, where I wrote a game engine in C/C++ and made a game with it.
The story
At the school I’m currently studying (2022), there is a final assignment where students form a team and make a game within a 4 month period.
The dream
I wanted to lead a team, and wanted to make a 3D game in my own engine.
The problem
My programming experience with C/C++ was limited. I had no prior experience with graphics programming. And I only had around 6-7 months to get my engine up and running. My favourite type of challenge.
The work
I broke down a vague list of features I needed to support to make the game I had in mind.
Then I made them. Done and dusted… not quite.
Chapter 1 - Get something to work
In class, we learnt how to detect collision between basic 2D primitives, and different ways to resolve them. In the end each of us wrote our own physics library, and displayed it with the framework that was provided.
My priorities did not include physics. Instead I quickly began to write a basic 2D renderer to use for my physics assignment. Since tools programming is one of my favourite areas, I also wrote the most basic UI library ever and ended up with something like this:
In addition to basic physics collision and resolution, I learnt about file handling, loading GLSL shaders and setting up a 2D renderer. This was a good foundation, but there was so much more work to be done.
Chapter 2 - Add basic 3D rendering
The UI library I had was horrid! That thing was not usable at all. So I began to write one anew.
While I was working on my own UI library on the side, as a class we began to learn about basic 3D Rendering and loading models.
At this point, I had integrated Assimp which allows me to load Obj and FBX files. I also had implemented basic Phong shading and directional lighting.
Chapter 3 - Panic, ask for help
I was running out of time. But I continued to work on the engine alongside other school assignments and projects.
My game needed shadows and Point Lights. By this time I had been introduced to a wonderful place to learn all about 3D Graphics in OpenGL: LearnOpenGL.com
After I started researching online and learning the features I needed to implement, the development took off.
Chapter 4 - It’s just the beginning
In order to make this project happen, I had to make tradeoffs. The game play is 2D, which simplifies a lot of things. For example I didn’t really require 3D Physics. But the visuals are 3D. So another feature that was missing was Skinned Mesh animations. This was a fun one, let me tell you. Because I was relying on my own maths library, this really tested the reliability of my code. After fixing a few nasty bugs I experienced the highest state of euphoria in my life.
Things were… moving. But eventually I got it to work.
Chapter 5 - Get people on board!
It was time to form the teams. I had pitched my idea in front of everybody. The only thing left to do to keep the project afloat was to get people on board. Fortunately, Wesley (our Producer / Level Designer) had decided to join this project before I’d even pitched the game. So I just had to reassure the Artists that we could make something beautiful with this Tech-Stack.
Time to promote the engine to the artists!
After going back and forth, presenting the engine multiple times, and pushing the graphics capability, some brave people decided to join. Wesley, Zac, Max, and Angelika… thank you for putting faith into this project.
Chapter 6 - Panic, it’s happening
Now it was time to write some tools:
Level Editor
Mesh Importer (renamed to Mesh Viewer)
Particle Editor (added months later)
The UI framework I had written was simply ugly, unusable, and again… ugly. Because I was writing the rest of the game in C++ instead of C, I had the option of integrating ImGui.
This marks one of my earlier mistakes. Instead of spending a very long time on some UI library, I should have focused on other important things. I care a lot about the look and User Experience of my engine and what I had written could not hold up that standard.
Now that I had a better UI library to use, I came up with a simple Level Editor and Mesh Editor so our artists and designer could get started.
Now that my team was in pre-production, I had to up my game. I wanted the artists and the designer to have a good set of tools to work with, and we needed to make a playable version of the game.
Chapter 7 - The pipeline
The pipeline we came up with was to make a block-out version of the levels inside of the level editor with cubes and placeholder models. Then export them out as FBX files so that the artists could load them up inside of Maya and make them pretty. Then we would reimport their work into the levels.
We wanted to take advantage of 3rd party applications while I was working on the engine.
We made a few levels with this approach and showcased it as our Alpha build. However, this method is incredibly fragile and slow.
But that wasn’t the biggest problem. Our tools were not ready to take the game to the next level.
Chapter 8 - Refactor, refactor, refactor…
I don’t remember the number of times I’ve rewritten different parts of the system. But I was rapidly learning and getting feedback.
Our lighting was okay… the tools were okay… but we could not make what we had in our minds like this. So I added a lot of new features to improve the tools and the renderer:
SSAO
Particles
Custom materials
Reworked Level Editor
Reworked Mesh Viewer
Reworked Post-process Stack
FMOD support (Yup, sound effects and soundtracks)
Our game was beginning to look good! The engine is stable, and relatively usable without my constant support.
Chapter 9 - Multi-threaded pipeline
Now that our engine is more capable, we’re moving onto a more conventional pipeline.
Now the level designer doesn’t have to wait for the artists to make the levels, and the artists don’t have to wait for the level designer to make levels.
While everyone is working on their own assets, I can focus on improving the performance, stability, and cooler visual effects.
Chapter 10 - Tsk, that was fun
I’ve skipped many other fun things that came up along the way. Such as attempting to keep the engine’s file formats forward compatible, adding “undo” functionality to the game, and how in the middle of the year I went to Singapore and tried to work on the engine at the airport.
We missed our “Gold” milestone, but we polished the game just in time for our industry showcase. I’m happy that people were excited to see this game and that they were not disappointed.
I’m going to miss working on this game with these wonderful people.
You can check out the game here: Time Merge . Demo
The Conclusion
Vim is cool. But I’ll stick with Visual Studio Code.
Jokes aside… thank you so much for reading this far. I hope this has been inspirational. I’ve definitely learnt a lot from this project and will continue to do so.
Working with others showed me a whole other dimension of game development which I appreciated and enjoyed the challenges of. I learnt a lot from my teammates and I hope they’ve enjoyed working with me on this game.
I want to rewrite the framework behind the engine based on the things I’ve learnt, and to add Vulkan support in the future. I’ll keep you posted.
Goodbyte for now :)