Creating a game engine, update #1
Following from some recent conversations with industry veterans about how best to develop and showcase my engineering skills, I’ve decided to start on my own game engine. I’m giving myself a timeline of five weeks to complete this project with an average workload of 20 hours per week, so the end result will showcase what I can do in 100 hours as an engine programmer working from scratch.
I have prior experience with systems engineering in general, and I have worked with the Tiger engine at Bungie back when I was an intern there. However, I have not made my own engine before; this will be an entirely new endeavor.
When it comes to projects like this, I tend to struggle with perfectionism and zeroing in on things that don’t really matter that much to outside users. As such, it is helpful for me to define goals that aren’t too deep that allow me to avoid wasting time on things that don’t matter that much1.
Current goals
The minimum goal is to produce a working engine. This means have a project that runs a game loop, renders something on screen (likely just something simple and 2D because rendering really cool, hyperrealistic things isn’t the point here), takes in user input, and transitions between states somehow. We don’t need to go overboard with the OOP or design or any one individual component; we just want to demonstrate the ability to create a working, usable engine separated from a specific game.
A common pitfall is to just implement a very basic game like Pacman, Pong, Atari Breakout…without actually creating an engine that is reusable between different game projects. With that in mind, I will aim to develop the engine as one project and a game using that engine as a second project. The “game” will likely still be very basic, but the point should be that it uses an actual engine rather than being a bunch of gameplay code loosely stuck together with some extra bits and bobs.
Reaching the minimum goal is unlikely to impress most people in the industry; plenty of people have made some sort of engine, and not all of those toy engines demonstrate an ability to contribute meaningfully to a modern AAA studio’s engine team. With that in mind, I have a short list of stretch goals, and I’d like to achieve one of them by the start of April:
- Multithread the engine and make the corresponding architectural decisions to make it easier to multithread with effective savings (this is a weakness in Unreal for example).
- Be able to reason what kind of multithreading is good in an engine beyond just “hey I made a job system so it’s automatically good”.
- Add Twitch chat integration s.t. messages in the Twitch chat (possibly prefaced with some indicator character like
!
) can be read and have some sort of effect in-game (e.g. moving the character, spawning additional game objects, etc.).- There is already an Unreal plugin that does this, which I haven’t experimented with at all. At a glance, I think I could try to improve on it by implementing a voting system or an API that lets other engine programmers choose how Twitch chat input is processed.
- This is a flexible enough idea that I could just do it in an existing engine like Unity or Unreal, or (as aforementioned) extend existing plugins.
- Could theoretically implement the same thing for YouTube Live chat too, although I don’t know how interesting that would be from a tech perspective.
- Implement ideas or extensions of ideas from some GDC talks(?? very vague and idk what people would find interesting at this moment)
Current progress
Not too far because I decided to play around with some C++20 features. The upside is that in theory, this engine will link faster. The downside is that in practice it likely won’t (unless the libraries I’m using suddenly update to C++20) and no big studio with an established engine is going to be using C++20 – it’s just way too recent.
I am following along The Cherno’s game engine tutorial where he builds the Hazel engine. Hazel starts out on Windows, though, and I decided to start out on Linux instead. I think this is good from a learning perspective because it forces me to actually understand the concepts rather than just mimic the actions from The Cherno’s tutorial - for example, I finally learned what’s the point of shared libraries and how to build them on UNIX! - but in terms of pure speed of implementation it’s disadvantageous. I thiiiiink it’s worth the tradeoff, but maybe it’ll come back to bite me. No biggie if it does, I think that’s just a matter of learning the balancing.
In summary, this week I learned about:
- how to properly structure a game engine project
- particularly the bit about having an engine project and a game project that uses the engine project. This is something that I think is missed by most tutorials and is certainly not something i would think about on my own.
- the point of shared libraries and how to generate them on UNIX systems
- on windows these are DLLs. In short, when compiling big projects you have a choice between generating intermediate object files or generating an intermediate DLL, and a DLL is a complete executable by itself - you can run a DLL, no issues with unresolved symbols or such that you typically get from static linking. more than anything, a DLL saves linking time because if you modify a file that is part of a DLL, you only need to regenerate the DLL instead of the entire project that uses that DLL (which would be necessary if you were using only object files). DLLs also let you save on binary executable size (at the cost of having to store the DLLs, but if multiple projects use the same DLL then it def saves more). One of the big downsides is that you can get into dependency hell (that is the technical term). Very rough explanation here, feel free to google or chatgpt it if you are curious for more.
- C++20 modules
- New C++ feature that, from what i can tell, aims to replace .h / .cpp structure in projects. Basically, modules will only export what the programmer says are explicitly exported, as opposed to
#include
directive which just includes the entire#include
‘d file. This reduces on linking time in theory. - Organization could be a little better, I think the ideal would be to put build module files (the ones suffixed .gcm when building with g++) into a
/usr/lib/gcm
folder, which would mimic the structure used in - I am unable to separate them into interface units and implementation units for some godforsaken reason, and I’m not sure if it’s a matter of me being on g++ instead of MSVC or if I’m just missing something stupid, but I wasted plenty of time on it and I really don’t think I’m gonna get more out of investigating further. So my interfaces and implementations are in one file each (analogous to putting implementations in your header file), which as far as I’m concerned is okay but not ideal at all. Quite Pythonic though.
- New C++ feature that, from what i can tell, aims to replace .h / .cpp structure in projects. Basically, modules will only export what the programmer says are explicitly exported, as opposed to
- correctly using chatgpt for advice
- i’ve been a bit stubborn about doing things “my way” and not relying on chatgpt, but i’ve experimented with it this past week and have found that its skill ceiling is a little higher than I gave it credit for. The way to use it is to ask it a question, then verify the answer either with a minimal demo or googling SO threads / etcetera. The big time saving is that you don’t need to word your question perfectly or sift through lots of not-always-clear documentation to get the right answer, which is a common issue i get when googling. I still had it answer things incorrectly quite a few times though, so don’t trust it 100%.
And this week I implemented:
- build system (just using Make for now) to nicely generate stuff, including an .so file for the sandbox “game” project
- module organization of my files
- basic test program that just prints “passing test”
Very light on concrete progress which always worries me. But I think there’s no real reason for me to be stuck on organization for a while, so I should be able to go faster this next week? We’ll see.
Oh btw I named the engine TuckTuck because it’s an engine and engines go tuck tuck.
Laugh.
Goals for next week
My productivity this next week is probably going to be on the lower side because I’m doing some vacationing in the UK. With that in mind, I would be very happy to get this far:
- add logging
- add imgui stuff following the cherno tutorial
- 2d rendering
This stuff should be mostly by the books? None of this should be stuff that’s particularly interesting, so I am hoping that it will go quick and that I won’t waste time on small things here. The modules are enough innovation for a while.
Main issue is just finding the time to do stuff. I don’t go out at night so i should be able to accomplish some stuff, but I suspect a nice 2d rendering scheme will have to wait until some time later.
-
Lots of programmers who haven’t figured out team skills yet will waste time on features that don’t really help the team. Teams, not individuals, are the smallest “value unit” in big software! ↩
Leave a comment
Your email address will not be published. Required fields are marked. *