"The biggest difference in performance between a junior and a senior engineer is in how many tradeoffs they can be aware of and juggle in their mind as they seek a solution to a problem." - Nuno Leiria
Nuno Leiria is a Senior Engine Programmer at Epic Games. Nuno has one of the most interesting and curious minds that I know. I asked him 5 questions to help me better understand the principles of Game Development and to learn how these principles can be used in other areas in a multidisciplinary way.
If you want to learn multidisciplinary lessons from other experts signup for the newsletter below.
1. What 3 books would you recommend for a person, like me, with no prior knowledge, wanting to understand the broad principles of Game Development?
i. Game Engine Architecture
ii. The Art of Game Design
iii. Blood, Sweat, and Pixels
This book is more focused on coding. It goes into great depth on most of the systems that make part of a game engine. It's in this book that you will get a sense of how complex this field is. A game makes use of many fields and platforms of computer science and they are represented in this book. The sheer breadth and depth is astonishing, and this knowledge isn't available to any type of game developer, mostly to game engine developers.
A very thoughtful friend told me this book changed her life. Enough said.
I believe this book will round your education. One for coding, one for design, and this one for production. Whereas the other 2 will go over your head in parts, this one won't. I would recommend starting here.
2. Some principles can be applied from one field to another. For example, engineers use the principle of ‘Margin of Safety' so that a bridge can hold more than the maximum displayed weight. This same principle could be used in personal finance, having excess cash to spare, when we budget. What principles from Game Development can be applied to other fields?
The number one takeaway doesn't come from game development but from computer science:
(i) Everything is a Tradeoff.
The computer is a very precise machine. Humans are subjective beings. Computer science is a field where precise engineering and subjective art meet, to create delightful experiences.
In this duality between precision and subjectivity, between art and engineering, there are tradeoffs to be considered. And this is just at the top level. We can follow the turtles all the way down, in a fractal way. Let's go through some examples at one of the bottom levels: To make some code run faster on the Playstation, maybe I need to increase the memory on the Xbox. Tradeoff. By decreasing the memory on the Xbox maybe I make the code less readable. Tradeoff.
All the way from the highest level to the lowest level there are tradeoffs to be considered. And most of them are hidden. As in all complex systems, sometimes you only realize the consequences of your change after you've made the change. Those are the blind spots. What are the consequences (read: tradeoffs) of the things that we do? Of the things that we don't do? Time, money? Sure. What about our feelings? What about other people's feelings? What about those feelings next month? Next year?
I believe that the biggest difference in performance between a junior and a senior engineer is in how many tradeoffs they can be aware of and juggle in their mind as they seek a solution to a problem. I think this transfers neatly from game development into 'the real world' :)
Bonus: Code that is considered beautiful, in an artistic sense, is considered so because it harmonizes all the trade-offs in a given context. Harmonizing tradeoffs leads to simplicity and beauty. In this sense, beauty is quantifiable.
If you want to make something more beautiful, identify all the tradeoffs and harmonize them. For example: Someone's face. Is it symmetrical? Symmetry is just harmonizing proportion. But too much symmetry makes you average. Average isn't that beautiful. Tradeoff. But then, how do you harmonize symmetry with uniqueness? Do you see how it becomes fractal? A possible answer may be that you round the symmetry with a unique eye color. Now there's some uniqueness. It's a better harmonization of the tradeoffs. And so on.
Refactoring means changing a piece of code in such a way so that we leave the inputs, outputs, and functionality intact. Nothing externally observable changes. But the code changes. Perhaps it becomes more readable. Perhaps it becomes easier to extend in the future. Perhaps it becomes easier to maintain and add new features. That's the purpose of refactoring, to make things better, simpler, or easier without actually changing anything observable.
OK, that's confusing enough... Let's try to apply this 'in real life'. Notice how when you do something repetitive, it gets boring? Take yoga for example. Maybe you always follow the same routine. At some point, it becomes.. meh. Maybe you could change the routine you follow; that would be changing the inputs. Maybe you could change the type of yoga you follow; that would be changing the functionality. Maybe you could change the way you do the movements; that would be changing the outputs. Or maybe you could refactor: don't change any of the inputs, outputs, or functionality. Change how you perceive what you're doing. Pay attention to how your fingers touch the mat. The specific pressure that is applied to each of them. Pay attention to where your attention is going in your body. These things will be different each time which means time will pass by faster and it won't be as boring as before. You just made an internal adjustment to the system. You changed nothing external and yet still made the system better. You refactored.
Bonus: Read up on Technical Debt. Refactoring is how you get rid of technical debt and prevent having to rewrite applications every couple of years. Good analogies to be drawn from here too.
(iii) Chesterton's Fence:
You probably already know this so I won't say too much. In practice, I try not to change or delete code when I don't understand why someone coded it that way. The same way, I'm wary of making changes in a certain situation when I don't understand the conditions that brought about the situation.
As a final note, consider reading: Algorithms to live by.
3. What small things make a big difference in game development? For example, in aviation pilots have checklists to avoid the most common mistakes.
(i) Code Reviews:
This is a practice that most good software companies have. Before checking in code to production, at least another person should take a look at it and point out potential improvements or errors. Sometimes there are multiple iterations of the write-review-write loop until the code can be checked in. It catches many mistakes, raises the code quality bar, and prevents knowledge silos.
(ii) Source Control:
This allows all code submissions to have a history and comments. It's a historical record of all the code and its changes over time. It lets us know who made a change, why they've made a change, what was changed, etc. As I said before, I try not to make changes unless I understand why the system is the way it is (Chesterton's fence). Source control allows me to gather the context for why things are the way they are.
Bonus: Read this classic (old but still relevant).
4. What is the biggest misconception or the biggest mistake that people make in game development?
The Biggest Misconception from Outsiders:
"I wouldn't be good at coding or game development because I'm not good at math." It's not about math, it's about logic. Read up on formal logic, it's easier than it sounds.
"It must be so much fun, playing games all the time!" Yes, it can be fun, but developing games is a different activity from playing games. In fact, I noticed that the more I develop the less I play. It's hard but also very rewarding.
Misconception From the Past:
"Videogames incite violence." Or "Videogames are only for male teenagers." This one changed when mobile phones became popular. There are over 3 billion players now, and people don't discriminate against themselves.