I occasionally get asked about the game engine I wrote back at independent games dev Limebird Entertainment. Specifically, people want to know how you start such a massive project. 100,000 lines of code later, it’s easy to point at each and every subsystem you have, explain what they do and how, and what the important design decisions were. You could probably even explain the reasoning that led to it being created at some point.
But where do you start? When you’re sitting there with a blank slate, what’s on the first row? The problem here is you’re starting something massive that you probably know next to nothing about. Do you open up your editor and create a file? Which file? Or do you start designing your architecture on paper or a whiteboard?
It’s a reasonable question to ask, and also an utterly pointless question to ask. My answer is “anywhere”. The important part is not where you start, but that you start — and that you keep going.
Identify one piece of code you need, and start writing it. You’ll be facing a million decisions anyway — what build system do you put all your stuff into to get it all to build on all your target platforms? How do you set up unit tests for your code? What version control system should you use? How do you design system X? How does that fit with system Y? All of these questions are things you need to deal with, and the only way to deal with them is one decision at a time.
One of the important things to realize is that the normal way of working in a development team doesn’t really mean much in this situation. How do you prioritize one component against another when you’ll need them all to get anything at all? Do you even know all the components you’ll need? You may think you do, but you’ll find out you don’t. The important part is to get going and keep going until you can start iterating properly on your code base.
Still, some tips:
- As your first code file, pick something you’re reasonably familiar with to get going. Regardless of the scale of the project, there’s going to be some small part of it that resembles something you’ve done before — do that first, to get up and running. It helps to be in familiar territory when compiling your first class, because that one first class is going to be where you get your environment up and running.
- Don’t over-engineer. Stay well within the bounds of what you’re reasonably certain that you’ll need. At this point, you want to keep moving to new parts of the project, so you can quickly reach a point where it starts doing something you want — so don’t waste effort on things you might need down the line. This sounds like simple advice but is actually quite hard, since you have no idea what you’re doing at this point.
- Accept that whatever you do will be replaced. You’re new to the things you’re doing. The first things you write will be incredibly uninformed and will undoubtedly be rewritten a few times as you learn about the system you’re writing. The important part is not that you write the perfect system the first time around, the important part is that you write the system and learn from it. Once it’s running, you can go back and fix it. Sometimes, the only way to get a system just right is to have done it once before.
- Make it do something. You can write core systems and design your architecture all day, and even with unit tests and all kinds of fancy techniques to prove to yourself that it works, you dont’ actually feel it until you have something that runs. Even if what you have is just a simple rotating triangle, the thrill of having a rotating triangle in your own game engine is a lot better than seeing the TriangleRotationTest pass.
So where did I start? We had a very brief discussion on how our design would look like, and what code we needed on a very high level, and then set off coding. I remember coding up our first version of a 3×3 and 4×4 Matrix math code on my laptop at my grandparents cabin in the countryside that summer. It was somewhat buggy, and I didn’t really know what I was doing… but it got the ball rolling.