Build Games with Your Game Engine
When building an engine, there are some obvious ways of testing your code like unit and integration testing. While these traditional software engineering practices help with certain systems, like a math library, it isn't obvious how they transfer to something like an engine which, as Casey Muratori put it, is an amorphous blob of input. Games have a different ecosystem for testing than software. For us, the way we were able to test our code was by a three tiered system: first with tech demos, then with sample games, and ending with a game jam. Tech demos tested if the feature was functional, sample games tested the feature in a gameplay setting with the engine as a whole, and the game jam tested the actual usability of the feature. Lastly, there's one more major reason to build a game: The only way we were able to complete our engine in 15 weeks was because we targeted the engine's features at an existing game that we made. We didn't just target the engine at a genre a genre, or an idea of a game, but an actual, designed game.
Specifying the genre of the engine isn't useless because it can help guide as a reference of which features are engine related and which are specific game related. It can be used more in the beginning when designing the architecture, however, ultimately, the game really is the decision factor of what features are needed by the engine. For example, most twin-stick shooters don't need physics but if the game you've designed does, you aren't going to not develop physics because the genre says it's uncommon, that's one of the benefits of having your own engine!
You may argue against making a game saying, "I'm interested in learning engine development, not making a game", "I've made games before, I know how they work", or any other excuse not to build one but don't listen to yourself. Although for us it was useful to have the game designed and implemented in another engine, this doesn't have to be the case for you. Having the game developed in another engine helps to visualize what an engine feature should be capable of, but it can be just as good to have a game design document. The main part of this is to be able to deconstruct a high-level game mechanic into what engine requirements it relies on. This will also help with knowing your priorities and dependencies of your engine features.
Having a target game for your engine will stop overscope, feature-creep, and building features that will go unused. With us, we began wrapping the GUI library Dear, ImGUI, which for those of you don't know is a library dedicated to GUI. What we found was that if we didn't restricted ourselves to just abstracting what the game needed we would have lost an additional week to just abstraction of features that weren't actually going to be used!
Another use of a target game can be pulled straight from game design, it gives you design pillars to make your decisions. For each decision you make with the engine ask yourself, "does the game need this?" If the answer is no, put a
TODO there and keep working on features that the game needs. Especially if you are working on a team, you can trust that everyone is furthering the engine each day because no one is going off in their own rabbit-hole of development.
A target game also gives you a way to showcase your work, others will be able to contextualize what you've done and you will be able to see what you have left to do. This can act as great motivation to help keep the project done, it is a similar feeling to when you get your first triangle rendered or game mechanic prototype working. Also working incrementally like this will help you set a point when the engine is "done". We aren't going to say you will ever feel like the engine is ever truly complete, but when you have the target game working and not completely hacked together you will be able to say it is done.
"Okay so I can just build one game." We wish. Before starting this project we dismissed the idea of building multiple games and an engine in 15 weeks, we even dismissed one game originally, but each game will help prove you engine is actually progressing outside the actual engine project. These games don't serve the same purpose of the target game, nor are they the same scale. The target game is what drives the engine decisions, these sample games need to live with those decisions and work around those constraints like a developer would be forced to. We would suggest you try to mimic some pre-existing design with each of these game, and have the game focus around a single mechanic. They don't need to be polished, master-pieces, it's better if they aren't.They're purpose is to use features in a game manner, which is almost certainly different than how they were tested through the tech demos. Another added benefit is if you can convince another developer who didn't develop that feature to use it in a game, this will almost certainly find bugs and API problems that the developer hadn't thought of originally.
These games aren't meant to increase the scope of the engine. Don't let them drive new features. However, if you notice multiple games need the same type of system that may be an indication it should be included in your engine. This is also a good time to notice if a certain feature needs to be hacked around or is too specific to be used by multiple games, that it may need to be refactored. This is even the case if the feature is for your target game, because that may mean you have just built game logic into your engine.
If we hadn't had this three tiered system of testing, the correctness and usability of the code would have suffered. The individual technical demos served an additional purpose past testing the barebones engine feature, we were able to provide these during our game jam as examples of how to use the engine. Beyond the game jam, these levels act as the living documentation of how to use each system of our engine, and although features are integrated in some capacity, each demo attempts to focus on one thing so a game developer can get a better sense of that from just one level. It is fairly obvious why the tech demos helped with correctness, they were the levels we used to ensure our feature worked, however testing a feature in an isolated setting like these levels isn't what games are about. Games have multiple features working side-by-side, and with this added element, as well as not knowing exactly how the feature will be used, the games found other bugs that the tech demos weren't even testing for or considering.
We would recommend that if developing an engine, especially one without software development testing, that you start developing demos and games as soon as you can. You don't have to wait until the engine is export into a dll or exe format to build levels, you should be able to start developing them within the engine (and eventually transfer them into another project). The point at which making games made sense to us was once we had our scene graph hierarchy implemented. All code examples prior to this point are hard to translate into usable examples, as any examples before was mostly hacks in the main engine loop. This is why we'd recommend pushing to get the scene graph hierarchy done much sooner than we had, which was Week 6. The scene graph doesn't rely on as much as you'd believe to start; for example you may associate having a scene graph with models or components but those are needed to start.
Remember, you are building a _game _engine whose sole purpose is to help create games. If you don't develop at least one game with your engine you are disconnected from you user.