Despite best practices and an abundance of engineering talent, writing high-performance, parallelized, and memory-safe code, at that scale of complexity, remained fraught and error-prone. Bear in mind, this predates the advent of C++11 (aka the 2011 edition) which heralded efforts to somewhat modernize the language.
Even so, manual memory manipulation is easy to get wrong, and research from multiple vendors describes this category of error as responsible for 70% of security vulnerabilities. Into this context steps Gray don Hear, a Mozilla employee, introducing a potential solution to the roadblock: Rust, the hobby language he'd been tinkering with since 2006.
In 2012, Mozilla would formally announce Servo, an experimental research project to re-imagine a browser engine built with memory safety and concurrency as first principles. These early days of Rust are described as a Cambrian explosion of ideas and wild experimentation.
Still, most in the industry, while admiring the optimism in taking such an ambitious moon shot, remained pessimistic about the prospects of success. Perhaps as significant as the feature list, was the number of failed experiments left behind on the cutting room floor, the team unafraid to pare down the language to its quintessential elements.
The industry and community started to take notice, and Rust began its impressive, and as yet unbroken, four five year streak as Stack Overflow's most beloved language. They, in turn, have contributed to Rust's impressive technical aptitude, but have also fostered a sense of reverence and fondness not often witnessed in other languages.
There simply is no other industrial language that offers the same speed and low-level control, whilst writing programs in the large. In the last decade modernization of the standard has done well to uplift it from its C roots, but the experienced programmer must build up an arcane lore of which features are blessed, and which machinery is dangerous.
In this blog post, Rust contributor without boats defines an import quality about abstraction: However, this is making the subtle point that it's competing against a secondary force: a more expensive abstraction that justifies its cost by being more comfortable and convenient.
We see this writ large in the rise of popular game engines that eschew the complexity of C++, the most notable being Unity. End users write code in C#, a more forgiving and ergonomic language, creating a boon in developer productivity and a reduction in iteration time.
The garbage collector eliminates an entire category of errors by removing responsibility for memory management from the end-user. The experienced developer can still create a performant experience, however, this demands plugging the leaks in the abstraction.
They must build a mental model of the machinery behind the curtain, a collection of arcane wisdom that bans many of the original conveniences, lest they disturb the garbage collector. Better resourced AAA studios generally choose Unreal or in-house engine tech built on C++, able to absorb the overhead for long term gain.
Writing optimized code is often about taking the way we, as humans, naturally think of an idea or algorithm, and instead expressing it in terms that favor the computer. This act often harms the legibility and understanding of a program, which makes it much harder for us, the humans, to reason about its correctness.
They must take great care to ensure data is appropriately loaded into memory before operation, and then responsibly disposed of afterwards. A difficult dance in which missteps either cause dramatic crashes or else subtle and hard to detect vulnerabilities.
At the other end of the spectrum, garbage collection promises the programmer it will automatically deal with the problem on their behalf. Rather than hiding this complexity, it accepts that computers are hard for humans, and instead tries to save us from the dangerous bits.
In the same way that static typing exists, very clever people have figured out how to make the compiler eliminate a whole category of memory and concurrency errors. Ownership makes some familiar patterns difficult or impossible and demands new ones be learned in their place.
To a developer standing on the shores of 2010, git, a new version control system with a steep learning curve, may have seemed like a risky investment. But, in the ensuing world of GitHub, it's hard to argue the effort was wasted, even if some workloads (i.e. large games) still require alternatives.
Ultimately, we will only know by the volume of mud we've dug through in the trenches, and admittedly, it is far too early to collect this data for games. These companies aren't looking to throw out multi-million line codebases and rewrite everything, but they are, where it makes sense to do so, choosing Rust for self-contained new projects.
Compiler tooling, documentation, error messages, cross-platform support, modules, dependency management and packages are all first class. Still, to the beleaguered operating system kernel developer, sequestered away writing C, it's hard to overstate how exciting the chance to have nice things must feel.
As a systems' developer, Bryan Cantrell, explains in his highly entertaining talk, with enough experience and care, it is possible to write well-behaved C code. Compelling, except, as a source of garbage collection pressure, game developers soon learn to steer clear.
Rust iterators, the equivalent of Line, are available as zero cost abstractions, closing the gap between how humans think and what the machine expects. Strict read/write rules on mutable data allow Rust to promise fearless concurrency.
Whilst each has different memory models (Swift is C++ like, and Kotlin is garbage collected), they represent the state of the art on their respective platforms (iOS and Android). With the groundswell and energy around it, and new language release every six weeks, this gap has been closing rapidly.
For example, anybody building a desktop application today would be frustrated by the lack of de facto GUI (Graphical User Interface) tools. Building new GUI systems is an elaborate multi-year effort, but here the vibrancy of the package ecosystem and community shines.
Though an overabundance of choice can ultimately become its own burden, there are already enough building blocks available to begin answering these questions. Modern game engines are a vast orchestration of different technologies, of which the choice of programming language is only a small piece of the pie.
That's not to say inter-op is impossible, C can be used as the lowest common denominator to glue the two together, an operation that demands a strong stomach. I had initially assumed graphics programming would be one of the last holdouts, where VFX are built with rudimentary C-like shader languages.
In the case of git, GitHub was the killer application that allowed it to out-compete rival distributed version control systems, and ultimately disrupt the sector as a whole. Unity had many compelling features: the ease of use and price point was a revolution in democratizing game development.
Unity built on that success and mind share to eventually compete and disrupt far beyond just the mobile space. It maintains their access to a broad talent pool and maximizes chances new a platform or middleware vendor will prefer their chosen engine.
Rust shows promise as a compelling language for engine development, and there is no reason this should be any different for programmers at the business end of large or complicated in- game systems. To a level designer making scripted gameplay content, building interactivity with Rust might be overwhelming.
It's not that a Rust flavored game engine can't solve these concerns, but building a robust user experience stretches beyond the programming language. Its plausible Rust will engender enough programmer goodwill to drive adoption, we are an opinionated bunch, after all.
It's reasonable to expect a game engine might follow suit; however, Godot already has a significant first-mover advantage. Despite the advent of accessible game engines, the expert skills required to produce content remain labour-intensive, and therefore expensive.
Procedural content and AI-assisted art tools have tremendous potential to usher revolution here, as seen in early research. We've seen massive venture-backed plays in the space, hoping to provide developers on existing engines an easy onboarding, so far with mixed results.
With investment from industry, some teams finding, and the announcement of an independent foundation, it does seem we're witnessing a dawn rather than a twilight. The C++ language specification evolves at a glacial pace, but there is nothing to prevent C++ from, ahem, borrowing some of Rust's innovations in memory safety.
We probably don't know how to make a simpler systems' language, but not every user, for example, needs to care about the default integer size on an obscure micro-controller. Their latest effort, DOTS, in part imagines a limited subset of C# as input for a custom high-performance compiler.
However, this franken-monster approach means rebuilding the engine from within and hoping the user base doesn't notice too loudly. By painting a realistic picture of Rust's roadblocks, it may seem I'm down on its prospects as a mainstream language for game development.
Whether my optimism is naive or not, my gut, and my experience of the Rust community's vibrant enthusiasm, tells me that we are heading towards a tipping point. For games, that day might still be far away, but I believe many of the technical hurdles will fall: because smart people enjoy a challenge and because it is there.
By building on the lessons of Amethyst, a prior Rust game engine, Bevy seems to have struck an ergonomic chord and generated a lot of enthusiasm. I find it hard to imagine established studios throwing out their existing tech, but a new entrant, free of any legacy, would be well-placed to invest into Rust.
Founded by Patrick Overland, former head of Dice and EA executive, we can tease from job postings that their first commercial title is sensibly made in Unreal.