There’s a frequestion request on game development forums and sites:
I want to learn how to make my own game engine.
Invariably, responses to the request say something like “make games, not engines” or link to the blog post of the same name (mirrored as the original is gone).
Predictably, some folks don’t take kindly to the advice, and they have seemingly good reasons why they disagree with the notion. One such reason is that they want to do it just for fun. I can’t argue with that reason at all; I do the exact same thing!
The other major justification for making an engine, however, I do have some issue with: when someone wants to write a game engine to learn how to make games.
I also take issue with the adjacent justification of wanting to make an engine to learn about game engines.
Learning by Doing
A strong way for many folks to learn, myself included, is to learn by doing. That is, practicing. What to learn to play the guitar? Play the guitar a lot, even though you’re initially really bad at it, until you get good. What to learn to algebra? While you’ll certainly need to do a lot of reading, it’s not going to be cemented as a real skill in your mind until you practice it over and over, hence why teachers push homework on us so much.
This extends right into making games. Want to learn to make games? Make a lot of games! They’ll be simplistic and probably buggy and not especially interesting at first, but those first steps will lead to second steps and third steps and eventually there’s potential to make something really great, but only after all that practice.
Learning to make games by making a game engine is another thing entirely, though. That would be like trying to learn to play guitars by practicing lutherie (making guitars).
Quite simply, it’s bass-ackwards.
What an Engine Is
There is no clear definition of “game engine.” Ask 50 game developers what an engine is and you’ll likely get 50 different answers… even if all 50 of those developers happen to work on the same engine.
For example, Wikipedia’s definition is that a game engine “is a software-development environment designed for people to build video games” which is not something I’d generally agree with, though it does describe a very common set of well-known engines.
See, every game has an engine. Even games made “without an engine” have an engine. A game’s engine is basically just the software that runs the game. That may be an off-the-shelf no-coding-required tool like Unreal, a some-assembly-required tool like Cocos2d-x, or a completely bespoke set of logic as in every early arcade or console or PC game before the advent of reusable engines.
A definition of game engine that I happen to like: a game engine is the interpreter for the game’s data.
The key bit here for this article though is that an engine’s entire reason to exist is to power a game. No game, no game engine.
Well, okay, “game engines” are used for things besides games, like Unreal used for filming the Mandalorian. I’m going to count that out though as that’s not really about Unreal as a game engine, but rather Unreal as a real-time 3D package. (Yes, this distinction matters. I’ll explain why later on in this post.)
This definition needs to be found for a specific project. If someone wants to make an engine, they need to understand what that means to them. Is it an interpreter for an existing set of game assets, like ScummVM ? Is it a framework for programmers to build their own games? Does it include tools like a game object editor or level editor? Does it include all the supporting services and APIs for user authentication, cloud saves, match making, and cloud hosting of game sessions? Does it aim to support multiple platforms? Which programming language(s) is the end-user team familiar with? What digital content creation (DCC) tools are the artists going to be using? Does the engine need to place real-time multiplayer as a central feature? Is the goal to provide a framework than some AAA developer could base a multi-million dollar game on or is the goal to provide a point-n-click tool for hobbyists to build simple games? Is it for 2D or 3D games or both?
Each of those questions can impact what an engine is and what it is for and can completely change the course of development for any engine project.
Engine Strengths and Weaknesses
Every engine - every piece of software, every technology, every process, every thing really - has strengths and weaknesses.
It’s rare to talk to a game dev using Unreal who won’t speak about the difficulties in using it for games that don’t happen to look and play similarly to Epic’s major titles (previously Unreal Tournament, then Gears, and now Fortnite). That’s not because of any failure on Unreal’s developer’s part, either! It’s just a fact of having to make tough calls about tradeoffs.
There is rarely a single “best” solution to a problem. When developing something like a game engine, intelligent choices need to be made about which things to optimize for. When making a game-creation suite, similar choices need to be made.
And choosing to implement multiple solutions to cover all the bases likewise is a tradeoff, if in nothing else than time and money and complexity.
The point here is that any engine is going to be really good for some games and a very poor fit for other games. There’s no avoiding being poor fit for some games, especially when an engine is young. Unreal is a lot better for a lot more varieties of games today than it ever was, primarily because Epic took so much feedback from so many customers making so many games.
Another case study might be Untiy. Just to cut to the chase and be perfectly frank, Unity was awful for almost any use case in its earlier years. Really, anything before Unity 5 was a pure frustration for all but the simplest of games, due to a variety of outright missing features, serious usability speedbumps, showstopping bugs, or the requirement to work around Unity to achieve game features. This wasn’t just for “major” games, either; even smaller indie games would run into these kinds of problems at high frequency.
Obviously, Unity is a lot better these days and is quite suitable for making a wide variety of games, big and small; this is only because, like Epic, the developers at Unity took a lot of feedback from game developers and iterated on the core tools necessary to make their games. Again, this early roughness isn’t the fault of Unity’s developers!
It’s because Unity had no real use cases in the early days; it had no specific games for which it was made. It was a group of very experienced game developers putting in their ideas of what a game engine should do to enable easy game creation, but even with all that experience, without a real use case there’s no way to qualitatively decide on which tradeoffs should be made, even where those tradeoffs are just whether feature A should be implemented before feature B. The turn-around for Unity wasn’t that the devs got any smarter (they were already super smart!) or more experienced or anything like that; it was that they had the feedback of a lot of game developers and used that to guide their development so the engine worked better for those games.
Every game engine is built on choices, and those choices - for a game engine that succeeds at enabling game devs - is motivated by the needs of the game(s) being built with the tech.
Games Provide Context
The real point to this whole article is that games provide context for a game engine.
The same is true in just about any context: drivers provide context for vehicles, moviegoers provide context for filmmakers, wine connoisseurs provide context for sommeliers, and so on.
For game engines, for developers making engines, having a concrete game or games to inform the decision making process and provide focused feedback is key.
If the goal is to learn to make game engines for games, then, simply making an engine in a vacuum without a target game is not useful. There are a million and more decisions to make in the course of engine development and without a game, there’s no way to know for sure if those decisions are being made “correctly.” And I put that in quotes because there is sometimes no correct choice without proper context.
This is where we start seeing things like Unreal’s use in filmmaking becoming relevant. Unreal didn’t start out supporting that use case and it almost certainly wasn’t in any of the developers’ minds in the beginning. However, there was a progression over time: games needed cut-scenes, and games wanted in-engine cut-scenes, so the engine needed to support these and the tools needed to provide the means for these scenes to be authored. Those tools then started enabling “machinema” like some of the early Red vs Blue shorts based on the Halo series, which in turn led to feedback about the tools’ capabilities for authoring these kinds of “long-form scenes.” Then AR/VR began requiring games and their engines to support real-time manipulation of real-life visual data. This started enabling experimentation with using game engines for real-time scene visualization in filmmaking. Which naturally allowed for feedback and direction from new paying customers in Hollywood.
It was use cases and contextualization, all the way down.
Note that if a new tool were built specifically for Hollywood, it probably wouldn’t be a great tool at first for game devs. Just as Unreal took many years and many steps and many feedback cycles to ready itself for film, a film-centric tool would likely take a significant amount of time and feedback to ready itself for interactive gameplay.
Understanding the Use Cases
There’s still the very real possibility that someone wants to write an engine, doesn’t care if it’s any good for any actual games, and just wants to experiment for learning purposes. Okay, that’s fair.
After all, despite everything I said earlier about early Unity being “bad” despite all the experienced devs that worked on it, the engine eventually ended up being a great tool. I have spent years tinkering with dead-end “engines” in my spare time for funsies, so does this article make me a hypocrite? (Jury’s out on that one.)
What I will ask anyone wanting to learn about making game engines is whether they have ever made any games on their own. Because, again, of context.
Let’s step back a minute. I brought up examples like learning to play the guitar earlier; the only way to learn to play the guitar is to play the guitar, and all that jazz about practice. Only, not all practice is equal. Dinkering around with a guitar for 100 hours will result in progress, surely, but not nearly as much progress as dinkering around with a guitar for 100 hours with a book on playing the guitar. Practice without direction is not as good a use of time as practive with direction.
This applies to game engines as well! Making a game engine without having made a game is like learning to play the guitar by just picking one up and sitting alone in a room with no books/videos/instructors/anything and trying to figure out how to play Hendrix’ Voodoo Child from memory.
Without having had made some games, a developer is going to lack a lot of context about which features an engine even needs to be accomplish any given goal.
A favorite example of mine is that almost every indie/hobbyist engine - even when it includes a full-featured editor and toolsuite and so on - completely lacks any kind of reasonable content pipeline that can get a game from initial prototype through release through 5 years of monthly patches on a live game service. If a developer (even one who’s made a few simple indie games!) hasn’t even shipped a larger game, odds are they’ve never even thought of the difficulties of supporting live maintenance of a game and being mindful of download size/frequency and so on.
Another example is an animation system. A developer with a little knowledge of games might understand that games need a way to play animations, and might even know out of the box that animations can be far more complex than just playing clips exported from Maya and require animation blending and possibly even an animation state machine, and what kinds of animation compression techniques exist and their tradeoffs, and heck they might even read about how animations need to synchronize with audio and VFX and deal network latency and control hitboxes… well, I could keep going.
Without having worked on games of a particular bent it’s exceedingly difficult to have any idea how to build an engine that could ever support those kinds of games.
This is one of the reasons that building a game from scratch is a better use of time than building an engine from scratch. With the game, the use cases are already fairly defined. Every time a roadblock appears (“how do I animate this character’s attacks while jumping?”) there is already a clear-cut context to guide a solution. Plus, since the goal is a game rather than an engine, there’s plenty of opportunities for just solving the direct problem rather than trying to build a framework for solving a general class of similar problems (most of which will never actually occur for the specific game).
To sum up my point here, building experience effectively requires a good guide, and for experience making game enignes that “guide” would be experience making games.
Legacy of Decisions
The original Quake engine’s use case was to quickly render (without hardware acceleration!) a complex static world. It used BSP trees as an acceleration structure. This had consequences, not least of all being that a dynamic world was somewhat out of reach; the BSP “baking” process was much too slow to be done in the engine and instead was performed by the editor. We see very similar trade-offs even today with features like light baking or navmesh generation, though we’re starting to see more and more games use real-time in-engine techniques for dynamic lighting and navigation. id has had to do significant refactoring over the years to convert its engine and tools to supporting the more dynamic games of the last decade or to even handle the level of polish and dynamicism found in the latest throwback-style Doom Eternal.
Unity’s original goal (according to Wikipedia) was to “democratize game development by making it accessible to more developers.” In other words, its primary use case was to enable point-n-click game development coupled with a very novice-friendly scripting solution with great tooling, which led to the use of C# via Mono. Aside from the difficulties I’ve already mentioned, some of these choices still affect Unity today. The use of C# and .NET for scripting means that fighting “garbage collector spikes” is still a significant portion of development time for Unity games, even for very experienced C# developers. The all-in-one editor makes some forms of extension particularly difficult. The black-box nature of all the core C++ code makes it difficult to reuse Unity APIs for common code that needs to be used outside of the Unity editor/runtime, like certain kinds of server environments. Those original use cases and very-intelligently-and-wisely-considered tradeoffs of the Unity devs has consequences, as any decision and tradeoff will.
Very early PC games were often written in low-level non-portable systems languages. Even games as “recent” as Roller Coaster Tycoon were developed primarily in assembly language. The reason was a pretty clear cut need for performance; higher-level languages, which few existed at those times, were not particularly great at generating efficient code. The result then was a lack of portability. Games like Dungeon Master had to essentially be re-developed for some platforms, resulting in significant differences in graphics or sometimes even gameplay between different platforms’ editions of the same game. Again, the trade-off selected to favor speed was the right one, but the consequences of those decisions are very real.
This all boils back down to context. There’s always a tradeoff to be made, and making the “right” selection means having a guiding light by which to make those decisions.
That context, for game engines, comes down to a combination of experience to understand what a particular kind of game project might need and down to having specific games to inform final decisions and prioritization.
A Game Will Give You an Engine
The final reason that building games is better than building engines goes back to the definition of an engine. If an engine is just the software used to run and build a game, then any from-scratch game will necessary involve building out an engine. It’ll be a very purpose-built engine that may take some work to generalize to a new game, but it’ll be more than nothing. This engine will also have already had informed decisions made that ensure it actually works in those contexts, too, which is a lot better than a more typical from-scratch-without-context engine that doesn’t really work well in any context.
Make a game. Get a honest-to-goodness engine for free as a result of making that game. Use that engine as a foundation for building another game. Generalize and improve the engine to support all the new use cases of the second game. Rinse and repeat. Build some tools to support that engine, too. Whatever tools that end up being useful to make those games, really. Eventually, the “end” result is going to be a capable game engine and a capable toolsuite for making games for that engine. Bundle them together and that’s how you get Unreal, Unity, CryTech, etc.
To learn to make general game engines the developer already has to know how to make games, and learning how to make games will provide most of a general game engine ready for further educational pursuits.
That’s it. That’s the Tweet.