Optimization is paramount. To maintain 60 fps, you need to calculate your game state and render graphics in under 1/60th of a second. That's only 16.6[..] milliseconds. If you want to appeal to the high-end players with 240 hz monitors, you get less than 5 ms. When you're operating at that level of latency, every microsecond counts.
You start having to care about how your data is laid out in memory so that you can optimize cache usage. You start caring about branch mispredictions. Multithreading becomes an absolute must, but locks are landmines. If you're using a garbage collecting language, per-frame allocations are kryptonite and you re-use buffers to avoid unpredictable pauses.
Your profiler becomes your best friend. You're not just looking for good performance, but consistent performance. If there's a 3 ms spike in CPU time every 10 frames, your players will absolutely notice it and it will destroy the feel of your game. That 3 ms becomes a critical bug.
Sure, someone might occasionally pull out a profiler, but only if things start becoming visibly bad. But this is an exceptional situation, not the norm.
On the other hand, game engines are constantly engineered with features that go against performance: interpreted scripting languages, ad-hoc garbage collectors (for assets, not only for scripts), visual material editors[0], deep object oriented hierarchies with FAT objects (hello Unreal Engine), etc.
[0] Shader compilation stutter is something a lot of gamers notice and dislike and a common explanation for its existence is the number and complexity of shaders current games use. But one thing very few seem to notice is this is only the case in engines that allow designers/artists to create materials with visual editors that generate shaders without understanding the implications. In engines that do not allow that (such as current id Tech) and artist have to create their materials using a low number of predefined shaders you rarely hear about this issue.
I worked at the intersection of engine and gameplay for a decade, and I’ve personally never seen an engine dev who doesn’t use a profiler nearly every day, and I certainly did. If you watch game dev presentations at conferences (Siggraph, GDC, etc.) you will generally see profile-driven development for new engine tech, they use profilers heavily and monitor performance rigorously.
Sure people did use profilers and the engine did have various profiling views and i personally wrote some of them myself - both for profiling performance as well as I/O since for some time i also worked on loading/streaming too - but as i wrote, those were when things became visibly bad. Most of the time people were either busy trying to fix bugs or busy trying to implement new features - and optimizing them became something to care about later, if needed (and there was enough time). And TBH usually that was fine - at some point i found some big inefficiency in one of the engine's core data structures, but that same engine was already used for a well received game at the past and the inefficiency only became obvious because the current (at the time) game was several times larger. So the thing performed fine for the original requirements and, at the time, trying to do more would be a waste (after all, it wasn't until long after the original game the engine was made for was released that the decision to make a much larger one was made).
But it's definitely the hardest software domain I have ever tackled, and if only it were just software! Game dev is realy 6 other disciplines in a trenchcoat. Which disciplines they are depends on your game and whether or not you have help.
It is like an arms race that doesn’t even need to be played. Whatever is released gamers have shown they are fine with if the mechanics are great. Crysis tried to stand out back in the day as the greatest graphical experience and about all it was good for was a benchmarking tool. No one talks about playing crysis anymore. Meanwhile people are still playing on Bloodgulch as we speak. Still playing dust2.
There’s a seed of truth here, but at the same time, I’ve heard this mostly from people who learned certain programming patterns in school or in enterprise application development, and never learned embedded systems engineering, or just plain didn’t start with game development.
You might be referring to issues with specific game engines, or you might be referring to writing only scripts and plugins for an existing game engine, as opposed to writing a game engine, I don’t know, but generally speaking game coding absolutely can and should be clean. It’s just a different kind of clean than you might expect, if you’re used to thinking in terms of C++ inheritance or functional programming or design patterns you learned elsewhere.
Hard disagree. In fact, learning how to apply clean code and architectural patterns in game dev has kept projects manageable and on track and done nothing but level up my general software ability.