2 Years of Vulkan Engine Development


Well, almost. Technically at the time of writing it's more like 1 year and 9 months, but if you count the time spent planning before the start then it's actually well over 2 years.

The repo was officially created on 2.28.2021.

Anyway, pedanticism aside, these last 2 years have seen a lot of development on the Kohi engine, and have taught me much along the way. I might eventually make a video about this too, but I figure for posterity an article like this might go a long way to serve as a log and snapshot of lessons learned so far.

A Quick Review

To date, here are some quick stats on the project:

How Far it has Come

Kohi has progressed at an average of a feature per week over the course of its life. As the sole developer of the project doing this in my spare time, I'm happy with this and honestly a bit surprised I've been able to keep up that pace thus far (more on this in challenges below).

To give an idea, here is a non-exhaustive list of the features added so far:

Note that this list leaves out any troubleshooting, refactoring, and many of the under-the-hood Vulkan backend features.

For the record, this is actually the first time I am seeing this list of stuff done at this point as well. Dang!

Where it's Going

For the sake of follow-through on the above section, here are some of the features to come in the next year or so:

I Learned a Lot, Though

So my primary goals of this project were basically as follows:

Thus far, I feel it's pretty safe to say I've been successful on all three fronts. I have been told that folks are learning a lot from it, and that it's generally pretty useful, which is a huge validation. I appreciate y'all! We could use this to make a (albeit very simple) game as it stands. The biggest missing component is probably audio. And, as far as learning goes, there's been a bunch of that for me as well.

One of the really neat things about working openly like this is it almost always attracts attention of folks that are smarter than me, and likely know more than I do about a given subject. Opportunity to learn.

There's also the fact that, up to this point, I had not actually written anything more complex than a small renderer in Vulkan. I have done so in OpenGL, but not Vulkan. Opportunity to learn.

Reading the Vulkan spec will generally get you pretty far. I know it did for me. However, I'm not really the type of person who can just read a spec and then fully understand the thing right away. I have to get my hands dirty. I have to try the thing. And by trying stuff out, especially stuff that doesn't work, I learn. Many opportunities to learn.

So I want to jump back a bit to my prior Vulkan experience. As I mentioned, it was just a static renderer (really, a few), which meant I could take shortcuts like recording the command buffer once and running it repeatedly, loading up everything at the beginning before the rendering even starts, and not really worrying about unloading... well, anything.

Developing a renderer for a game engine is nothing like this though. There are so many more things to consider. Game engines, at least at the renderer level, need to be able to have all kinds of things thrown at them in any order and at any time. It is anything but linear. Furthermore, a game engine in many respects is ingested in different ways (namely the end product/game runtime as well as the editor). These in turn also operate completely differently, and thus have different requirements.

The biggest thing for me (and, I suspect, many others) is memory synchronization. Engines in the past that I've written were based on either OpenGL or an old version of Direct3D, both of which masked this away. Where I never had to worry about this in the past, I definitely do when it comes to Vulkan, and I definitely struggled with this in the beginning. I'll probably write up another post at some point about this point specifically.

Another point was all the extension and layer loading. This was again something not required by older APIs. I didn't necessarily struggle with this, but it made me think very differently altogether about only loading what you need.

Something else I hadn't attempted before this was an engine with the idea of supporting multiple graphics APIs. This made me think about the architecture of the renderer completely differently than I ever had before, and I'm pretty thankful at this point that I decided on that design. Vulkan on macOS via MoltenVK is great, but native Metal support is going to be a must at some point. Add macOS platform dev to the list of things I learned about as well. Previously the most I had ever developed on macOS was web-related stuff. Platform code is a whole other beast.

Vulkan really helps one understand what is going on under the hood of OpenGL and other APIs that mask away the complexity for you. It really makes one think about how render passes are handled, for example, and how those in turn relate to framebuffers and attachments in a way that was far more abstract otherwise.

I also learned a lot about writing code for the Linux platform during this project. For most of my career I had always used Windows machines, and for most of that time I has only ever used full-on Visual Studio for any type of development I ever did (outside of Android/Java work, where I used NetBeans or Eclipse instead). When I saw the direction Windows 11 was going (yet another thing I'll be writing a post about), I finally decided to take the plunge and make Linux my main OS of choice - my daily driver, if you will.

Before this, I had really only used Linux as a hobby/exploration OS, and never really took it seriously. I had learned about 4 or 5 years ago the value in not using an IDE for web development (I had switched to the lighter VS Code), and decided that when I switched to Linux as my full time OS that I would also ditch the full-blown IDEs as well. One could argue that VS Code has become a bit of an IDE (and it can be depending on how you configure it), but I like the raw power of working in the terminal and truly understanding what you are feeding to programs such as the compiler. All of this change is something I embraced as I started the project (which is why many of the first videos in the series take place on Windows, and I only later switched to Linux). I don't think I could ever go back to using Windows full-time at this point. I like Linux too much (and yes, even macOS most days, as a lot of what I learned and do in Linux carries over).

Closing Thoughts

To wrap this up (because it's getting kinda long), there is a lot more I could bring up here. I have ideas for some more targeted articles I may write in the near future with my learnings (specifically around Vulkan, and/or Linux/macOS). While this project has been helpful for those consuming it, it has also been immensely educational for me along the way. I think this is one of the reasons it's been easy for me to stick with it. Community support is definitely the big reason, though.

There are so many topics I want to research for this engine and implement, and several game ideas that I already have to test it that I don't see interest being an issue for quite some time.

Anyway, if you've made it this far, thanks for reading and yeah, that's about it. See ya next time.