25 years ago was launched one of the most significant and influential titles in video game history: DOOM.
The creator of this iconic videogame, John Romero, started developing games in 1980,then he co-founders Id software, an American video game development company known for having produced very popular games such as Doom, Wolfenstein and Quake. He participated in the development of hundreds of games and is now among the most influential game developers all around the world.
So it was no surprise that he was invited to deliver a speech at Codemotion Milan 2018, where he told his story from the beginning of his career until today. During his talk, he used anecdotes and prior experiences to build a set of 10 programming principles that apply to game development. In this article, we provide a summary of these principles, serving as a sort of “vademecum” for any game developers.
Keep your code absolutely simple. Keep looking at your functions and figure out how you can simplify further.
During his talk, John Romero explained that some of the current policies taken by software development companies should not be used in the context of game development. Software developers often put some TODOs in their code, as a marker to remember to fix a bug later, just because it is simple to solve and they prefer to continue with the rest of the development. Romero suggests exactly the opposite: fix any bug immediately, make the code polished and working, in order to maintain production code.
No prototypes. Just make the game. Polish as you go. Don’t depend on polish happening later. Always maintain constantly shippable code.
In the development of a game, it is crucial that the entire team must be able to test the game they are creating. Always, at any time of the development process. As Romero said (and this is part of principle 5), “we are our own best testing team, and we should never allow anyone else to experience bugs or see the game crash […]”. To allow testing during the development process, it is thus important to always provide defaults on load failure.
“It’s incredibly important that your game can always be run by your team. Bulletproof your engine by providing defaults upon load failure.”
This principle is, to some extent, a sort of corollary of the Occam’s razor principle. When you can do something simple, you should do it. There is no reason to complicate things and this is especially true when you are part of a game development team. Moreover, even if you arrive at a working code for your goal, if it doesn’t seem intuitive, or is difficult to maintain, it is crucially important that you stop and try to figure out how to make it simpler.
Throughout his career, Romero has had the need (and the opportunity) to build several game engines, some of which gained a lot of popularity in the game development community. This is the case with the Doom Engine (actually developed mostly by John Carmack), which is still downloadable and has been release with GPL License. In his talk, Romero explained how the ability of creating great games strongly depends on the tools and the engines used for building them. He told about how many tests he and his team did in order to find and chose the best tools for their games. The great results of their products are clearly due to the hard work in finding (or creating) such powerful tools.
Great tools help make great games. Spend as much time on tools as possible.
There are two main concepts summarised by this principle: firstly, the best testing team is made up by who developed the game; secondly, do not allow other people to waste their time and see your bugs. You might think that developers should be able to see all the bugs they program. But you can ask another developer to test your application, gathering more informed feedback and more help in fixing the bugs.
“We are our own best testing team and should never allow anyone else to experience bugs or see the game crash. Don’t waste others’ time. Test thoroughly before checking in your code.”
This principle is related to the first one. Instead of postponing your work on bug fixing, when you see a bug you should immediately work on that, and fix it. If you don’t do so, you can easily forget about it. Solving bugs later may cause a lot of struggle, and additional work. It’s wasting time.
“As soon as you see a bug, you fix it. Do not continue on. If you don’t fix your bugs your new code will be built on a buggy codebase and ensure an unstable foundation.”
Reusing code is one of the basic principles of object-oriented programming. But this Romero principle is not in contrast with it. It is ok if you can reuse some code that you wrote before, but when you are developing a game, remember that you are working for it, not for future games. When you will develop a new game, you will find new things, new ideas and new technologies, probably better than the current ones. With Quake, id software used new tools and a new game engine instead of reusing the Doom Engine.
“Write your code for this game only – not for a future game. You’re going to be writing new code later because you’ll be smarter.”
Using this principle allows creating more efficient code, and more flexibility with design choices and changes. Creating modular code is a way to put this principle into practice.
Encapsulate functionality to ensure design consistency. This minimizes mistakes and saves design time.
Discussing issues about the development process with other team members is very important. You can get useful feedback for easing the development. At the same time, you will inform other team members about what you are doing, so that they can help (or even “replace”) you in future stages of the development.
As with any creative art, programming requires the right amount of time and patience, which are different for every programmer. So it is important to keep in mind that every developer is different. You must acknowledge this, and respect other team members.
“Programming is a creative art form based in logic. Every programmer is different and will code differently. It’s the output that matters.”