Our website uses cookies to enhance your browsing experience.
Accept
to the top
>
>
Game++. Part 1.3: Game engine...

Game++. Part 1.3: Game engine architectures

Jun 16 2026

This book offers insights into C++, including algorithms and practices in game development, explores strengths and weaknesses of the language, its established workflows, and hands-on solutions. C++ continues to dominate the game development industry today thanks to its combination of high performance, flexibility, and extensive low-level control capabilities.

Before jumping into game engine architectures, it helps to define what we mean by software architecture and how it relates to games.

First, architectures are a real thing in game dev, whatever anyone says. Second, there turns out to be more than one. Keeping that in mind makes the rest of this chapter much easier to follow and gives you something to say the next time someone goes off about why a particular engine is either pure genius or complete garbage.

Most projects follow a similar pattern: code gets written, tools get built, a game gets shipped. The skeleton grows flesh, and only then do all the ignored problems come knocking because getting something out the door was always the priority. But sweeping problems under the backlog rug doesn't make them disappear.

Every program has an architecture, even if everything lives inside a single main() and somehow holds together on optimism and luck. The more interesting question is: what actually makes a game engine good?

Nobody builds an engine for fun. Engines grow from necessity—as development progresses, individual pieces get formalized and stabilized so they can be reused. An editor appears, then an asset pipeline, a dedicated I/O module, a renderer that earns its own codebase, and so on. Eventually a team of engineers gathers around all those systems to keep them running. Most teams only realize this after shipping—by then it's clear that you simply can't keep working the old way.

Another approach is for the game itself to be the editor, the engine, and the build system all in one—something that can compile itself into finished levels and logic. All game engines and editors grew out of games. Some of those games (and later engine-editors) became successful, and their developers rode that wave to buy more time and resources to keep building. Over time, somebody on the team (grown from within, rarely hired) takes on the job of keeping the growing machinery together, ensuring integrity within the whole system. Sometimes that person carries the title of Architect. More often, they are an engineering veteran who's spent years working alongside programmers, designers, QA, and production.

For the last ten-plus years I've spent every working day staring at the code of different games and engines, mostly large ones that have been around long enough to grow beards. Like any programmer who's spent a long stretch in one domain, I'd like to think I've developed an eye for good design or, at least, a nose for bad design. Every developer has lived through that moment when the code they were looking at was so bad that the only honest move was to comment it out and rewrite everything around it. Of course, "best technical decision" and "approved by management" are rarely the same thing. Terrible legacy systems often survive for a reason: they are ugly, but battle-tested. Everybody already knows where the landmines are. New code may look cleaner, but you still have to discover its hidden threats.

Few of us have been lucky enough to work with perfectly designed code. That very code, project, or engine that feels like a luxurious American sedan from the '70s—one that has everything you could want, you just need to know where the controls are—and it's ready to hit 100 fps with just a light tap of the gas pedal. Anyway, working with different codebases, I started noticing that game engines often resemble the teams that build them.

Once a team grows beyond five or six developers, some kind of organization becomes unavoidable—responsibilities naturally split along the lines of skill and experience. Everybody does what they know best: the internal database, the renderer, physics, the editor, tests, and so on. From a business standpoint that division looks perfectly logical—the right people in the right seats, less overlap, better efficiency.

Split the team and you split the knowledge, and suddenly different parts of the system struggle to interact effectively. Development then bogs down as specialists dig deeper in their own isolated subsystems and stop talking about the things that actually affect everyone. That artificial divide ultimately hampers knowledge sharing and leaves the engine's components poorly integrated with each other.

This pattern—the link between an engine's structure and the internal organization of the team behind it—was noted back in the 1960s by Melvin Conway. Conway's Law states that the structures of the organizations involved in designing a system will ultimately be reflected in the architecture of that system. Put simply, it's hard for a team to build something that doesn't end up looking like the way they communicate.

This isn't specific to engines, it goes for any team-built software. A company split into frontend, backend, and database teams rarely ships a system where those boundaries don't show—the architecture quietly inherits the org chart, whether anyone intended that or not.

Note. According to Johnny Leroy, the way to fix a broken architecture is to fix how the team communicates first. The architecture and the team that builds it have to grow in the same direction. Instead of building a system that inherits organizational weak spots, you reshape the organization so it naturally grows something more integrated and flexible.

If the architecture demands tight integration between different parts—say, between gameplay and the renderer—don't keep these teams working in separate corners. Get them talking directly: cross‑functional groups, pair programming, or cross‑review practices. The knowledge starts flowing and the architecture shifts with it.

A small warning before we continue. In the text below, the architectural labels may not be industry-standard and may be debatable.

Unity (Unitary Architecture)

The first time I looked seriously at Unity's internals—not the editor, but the engine architecture underneath—I was mildly horrified. This was around 2014, so perhaps some things have changed, but I'd not bet heavily on it. By then, Unity had already conquered mobile development. I expected a polished architecture and a carefully engineered roadmap. Instead I faced a patchwork quilt of components with three build systems haphazardly thrown together and sealed with a mono-VM. Just like "if it builds, don't touch it", even if it means workarounds everywhere and comments like "Don't remove this space", "Don't compile on Independence Day", or "Build with this constant first; if it doesn't compile, set it to 0." At one point, building the editor involved a separate wiki page listing 117 steps: compile this first, rebuild that second, set these flags, pray if it fails. And the editor had its own separate build system on top of that. But the origin story of Unity explains a lot.

It all started with GooBall, a game dreamed up in 2001 by students David Helgason, Joachim Ante, and Nicholas Francis. Their studio, Over the Edge Entertainment, ran into the classic indie problems of the early 2000s: expensive engine licenses, complex code, and a lack of resources. The guys shipped the game, but four years of struggle ended in commercial failure. What came out instead—built on that same game source code, those same approaches, and that same team—was Unity.

In 2005, Unity 1.0 was quietly shown at an Apple conference. An engine built for macOS X seemed to have little chance in a world where almost everyone played on Windows. But that turned out to be its advantage: the Mac was popular with designers, and shortly afterward it became a common platform for early iPhone development.

Unity stood out right away. Rather than wrestling with complex code, Unity's component-based approach lets you assemble objects like LEGO bricks—snap on physics, animation, or scripts. A visual editor, rare for the mid‑2000s, meant you could just drag things around with a mouse. Support for C# plus a simplified UnityScript made scripting approachable. The industry took notice.

The turning point came in 2008 when Unity shipped on Windows, multiplying its audience tenfold. The real liftoff, though, happened two years later with the Unity Asset Store—a marketplace of ready‑made models, textures, and scripts, most of it a dollar or free, which was manna from heaven for indie studios and solo developers. At the same time, the engine added iOS and Android support, right as smartphones exploded. Suddenly, one laptop and a good idea felt like enough to build a game. That's how Temple Run (2011) and Monument Valley (2014) came to be. EA, Blizzard, and Ubisoft followed in 2011, signing long‑term support deals and licensing the source code for internal use. By 2015, nearly half of mobile developers were using Unity.

The internals still resembled a large patchwork quilt: three different build systems, a pile of reinvented wheels, a partially modified EASTL library sitting alongside Boost and the standard C++ library. Different parts of the engine could use different STL versions, which meant copying data at the boundaries, for example, between the renderer that used EASTL and the editor which had its own custom classes and containers.

Tack on Mono with its own data exchange layer and you end up with a classic game engine architecture of the early 2000s. Not to be too uncharitable, I call this kind of architecture "unitary".

You may have heard the saying that programming languages come in two kinds: the ones people complain about, and the ones nobody uses. This analogy seems to fit here. For what it's worth, I have genuine respect for this engine, so don't let any of the above mislead you.

Big Ball of Mud

Code that grows without structure has a name: Big Ball of Mud, an anti-pattern popularized by Brian Foote in the 1990s. Among my colleagues I've also heard variations like Cup of Mud, Fancy Barrel, and Dirty Feet.

Note

"A Big Ball of Mud is a haphazardly structured, sprawling, sloppy, duct‑tape‑and‑baling‑wire, spaghetti‑code jungle. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. Information is shared promiscuously among distant elements of the system, often to the point where nearly all the important information becomes global or duplicated. The overall structure of the system may never have been well defined. If it was, it may have eroded beyond recognition. Programmers with a shred of architectural sensibility shun these quagmires. Only those who are unconcerned about architecture, and, perhaps, are comfortable with the inertia of the day‑to‑day chore of patching the holes in these failing dikes, are content to work on such systems."

Brian Foote

In practice, a "unitary" architecture may describe, for example, a simple game where event handlers are wired directly to handling logic without internal buffering or dispatching. Most games start out that way, and it works fine until it doesn't. For a tiny game with a few mechanics and screens, it's no big deal. But the codebase keeps growing. Without structure, every change turns into an uphill struggle, and sooner or later releases, testing, scalability, and performance all start to hurt.

This anti‑pattern is everywhere. Hardly anyone sets out to create a "unitary" architecture, but poor quality control and a lack of structural discipline will get you there eventually. Within such a system, any change in one class can break something completely unrelated, making every bug fix or tweak a gambling nightmare. At its worst, the project ends up as a jumble of source files, resources, and engine‑technical files.

What started as a three‑student project is now maintained by a team of 400 engineers. Unity Technologies employs 5,000 people, fewer than 10% of whom are programmers. Picture 2.1 shows a block diagram of Unity Engine, and there's nothing to worry about at first glance... Until you dig deeper into the C++ guts and try to change something.

By this point the "simple" architecture hasn't been simple for a while. Everything talks to everything: managers depend on other managers, states reference one another, events fire when nobody expects them to. Try to fix one thing and two others break. Changing one feature suddenly requires rebuilding half the dependency graph. The longer it goes without cleanup, the scarier the code becomes to touch. The cost of developing new features skyrockets under these conflicts, when you can't say what affected what, and where it's going to blow up.

Components never designed for reuse become traps for anyone new to the codebase. With no clear boundaries, dependencies, or isolation, reliability decreases. As a result, developers grow afraid to make changes, and the project stagnates. Picture 2.1 shows an overview of the Unity engine (version 4, 2014), and Picture 2.2 shows a class‑dependency diagram where each chord represents a relationship between the classes and subsystems shown in Picture 2.1.

Picture 2. 1

Picture 2. 2

The Cup of Mud architecture (or a legacy bog) describes localized pockets of mess inside an otherwise orderly codebase. Individual functions, classes, or modules become islands of chaos: a function may have dozens of parameters, multiple nested conditions, and mixed logic from different levels of abstraction. These spots usually start as temporary fixes or emergency patches that nobody ever got around to cleaning up. Smaller in scale than a Big Ball of Mud, these pockets still breed bugs and slow development down, as developers avoid touching them.

Fancy Barrel is about code with a clean, attractive API that hides chaotic, poorly organized internals. It boasts good documentation, elegant method names, and modern design patterns on the surface, while the architecture remains tangled and unstructured. A beautiful facade that conceals a "barrel" of technical debt and creates a false impression of quality engineering. The problem surfaces the moment you need to extend something or fix a bug. At that point the pretty interface is all you have to show for it.

Dirty Feet ("as if someone has tracked mud through the whole house") and Pigsty both describe code that has left a mess scattered across the system. The hallmark is broken encapsulation, where changes in one module force modifications in dozens of seemingly unrelated components. Anyone working in this codebase ends up poking around in unrelated corners of the system to implement a single feature, eroding logic and building up hidden dependencies. The result is code that's hard to test and even harder to isolate, as every component drags in a pile of side effects and demands complex setup.

Unreal Engine (Layered Architecture)

In 1991, Tim Sweeney, the founder of Epic Games (at the time just Epic MegaGames), started building editing tools for his first titles. It all began with a top‑down adventure‑puzzle game called ZZT, with bare-bones graphics (Picture 2.3).

Picture 2. 3

Players explored maze-like levels, fought enemies, and solved small puzzles, all rendered in plain ASCII characters in DOS text mode. ZZT was never going to turn heads for its graphics or gameplay at the time, but Tim's approach to programming—and especially the built‑in ZZT‑OOP level editor—established the modularity principles that later evolved into Unreal Engine.

ZZT proved successful, bringing its author about $100 a day in shareware sales. Enough to convince Sweeney that game development might actually be a real career instead of a hobby. Hiring a small team from a level‑design contest for ZZT, he moved the business out of his parents' house, and a five‑person team got to work on the next project—Jill of the Jungle. In 1992, Epic shipped Jill of the Jungle (Picture 2.4), a DOS platformer that introduced more advanced tools such as sprite animation, movement physics, and particles. The bigger shift was a growing emphasis on a component-based approach: Tim built objects from data structures based on standard engine components, making it possible to override object behavior without touching the rest of the code. You could create new enemy types, change their AI, or add interactive level elements through scripts.

At a time when most studios essentially rebuilt their technology from zero for every game, Tim's approach was different. He separated the game into three distinct layers:

  • the engine (low‑level systems: rendering, physics, sound);
  • the content (assets and base logic);
  • the scripts (configuration files and high‑level logic).

Those ideas grew into something bigger. In 1998, Epic released the first version of Unreal Engine alongside the game Unreal.

The structure of the first engine-game looked more disciplined—rendering, shared systems, scripting, tools, and editing workflows existed as relatively independent pieces. On top sat UnrealEd, while gameplay logic leaned on UnrealScript, an object-oriented scripting language with class inheritance that made modding significantly more accessible.

Picture 2. 4

Picture 2. 5

Other technical advances followed: dynamic collision, 16‑bit color, richer lighting, and tools that let developers run and tweak parts of the game directly in the level editor. The game was a hit, selling over 1.5 million copies. In 1999 Epic released its second game, Unreal Tournament, which was a "lessons learned" exercise that added built‑in networking support to the engine.

In 2002, Epic released Unreal Engine 2, debuting publicly alongside America's Army—a free multiplayer shooter built to boost public interest in military service. It was the first time the army had used large‑scale game technology for a public audience; the game picked up several player‑voted awards along the way.

Although Epic's primary focus remained PC game development, Sweeney and his team once again recognized where the market was heading: toward consoles. The idea of creating a single engine that would allow developers to release games on both PCs and the Sony PlayStation 2, Nintendo GameCube, and Microsoft Xbox was highly appealing. Unreal Engine 2 also reflected Sweeney's interest in modularity—unlike many competitors of the era, Epic avoided treating each engine release as a frozen artifact. So, after its first drop in 2002, the engine was regularly updated and modified.

Flexibility became another key pillar of Unreal Engine 2. While previous engines from other companies were mostly locked to a single genre—first‑person shooters—the Epic team recognized that giving developers the freedom to work across genres would be a huge competitive edge. Integrating the Karma physics engine, a particle system, and other new capabilities quickly turned UE2 into an industry standard, powering titles such as BioShock and Thief: Deadly Shadows.

Unreal Engine 3 shipped in 2006, with the first Gears of War as its flagship. The engine's growing platform support opened the door to iOS and Android releases. This update was aimed more at the player-facing side of things—the internal architecture stayed largely unchanged, but the renderer got a significant overhaul: per‑pixel lighting, better physics, and much more.

Game developers often rely on layered architecture to keep their codebase well‑organized. Even though Unreal Engine was shaped by one specific person's vision for a long time, it scaled well to a large team, giving the engine and its subsystems both structure and room to grow.

Looking at how the engine's components connect (Picture 2.6), it's clear that while different parts still talk to each other, there are far fewer connections than you might expect. A layered architecture maps naturally onto a component system: scene objects, physics, or scripts—each sitting at its own level of abstraction. This ends up becoming the de facto standard and the architectural foundation for most studios building games on top of the engine.

Once again, back to Conway's Law, which says that codebase structure tends to mirror the way teams are organized, and Unreal is a textbook example. Its development team is split into focused groups—UI/input, gameplay, AI (responsible for NPCs, interactive objects, and enemies), and a dedicated engine‑optimization team. This structure naturally tends to show up in the game teams building with the engine. And yet, individual developers may take on tasks beyond their usual scope or complete internships in other teams—this is just part of how Epic operates.

Picture 2. 6

People are people, and developing with Unreal can be surprisingly comfortable—comfortable enough that teams sometimes slip into a "default architecture," following the engine's templates and conventions without questioning the reasoning behind them. A project can even drift into a "unitary" architecture, where developers simply start coding without a clear plan. For a while the layered structure the engine provides holds things together, but again, without real discipline behind it, the codebase gradually devolves into a Big Ball of Mud.

As of 2023, Epic Games has around 4,000 employees worldwide, spanning game teams, publishing, the store, and the engine itself. Open‑source estimates put the number of people working directly on the engine somewhere between 500 and well over 1,000. That includes around 200 programmers focused on graphics, physics, and optimization. Beyond them, there are technical support engineers who maintain the GitHub repository and handle incoming commits, as well as technical writers and course engineers. Developers for VR/AR and mobile, and a large division dedicated to Virtual Production, CAD integration, and support for major game and film studios—together adding roughly 400 more people.

Author: Sergei Kushnirenko

Sergei has over 20-year experience in coding and game development. He graduated from ITMO National Research University and began his career developing software for naval simulators, navigation systems, and network solutions. For the past fifteen years, Sergei has specialized in game development: at Electronic Arts, he worked on optimizing The Sims and SimCity BuildIt, and at Gaijin Entertainment, Sergei headed up the porting of games to the Nintendo Switch and Apple TV platforms. Sergei actively participates in open-source projects, including the ImSpinner library and the Pharaoh (1999) game restoration project.

All parts

Game++. Part 1.1: C++, game engines, and architectures

Game++. Part 1.2: C++, game engines, and architectures

Subscribe to the newsletter
Want to receive a monthly digest of the most interesting articles and news? Subscribe!
Popular related articles

Comments (0)

Next comments next comments
close comment form