id Software Principles
Gamedev history is important. How games that defined current genres were made? By who? What was their thinking, their business & social situation, their hardware constraints? Can we understand the success or failure of a game, of a team, and prevent making dumb mistakes? Luckily, this historic time was just 40 years ago. These gamedevs are still here, still making games, and some give talks to share knowledge. So let's learn!
I'm no hard FPS player, but I watched a talk given by John Romero at the 2022 Strange Loop conference about the core principles of its team during the 90s. I resonate with most of them, so I transcribed them here, with some context & personal notes.
id Software was created in january 1991. During their first year, with a team of 4, they published 13 games! They spent 2 months on each game, 2 games at a time. They programmed in C & Assembly for Apple II, Commodore 64, MS-DOS, developing their own engine & tools during the process. They notably developed 7 Commander Keen games, Hovertank 3D and Catacomb 3D, then started working on Wolfenstein 3D in december 1991, working on it for 4 months. Later on, they developed Doom, Doom 2 & Quake (about a year of dev each).
It is peculiar. Compared to today, these are really short developement cycles. This is interesting and worth analysing.
id Software is also known for their revolutionary tech and tools. They were pioneers of real-time 3D rendering, level editors, community-created content, multiplayer, & FPS level design. Doing this groundbreaking work while fast shipping at the same time seems like wizardry to me.
So when a guy from this small team explains what core values they had during developement, I listen and take notes.
Warning : These are very dedicated people, working 12 hours a day, 6 days a week, for decades. their work/life balance are not standard, and shouldn’t be. They live by their craft, and some of them have partners also working on games. They make sacrifices to achieve and sustain their dream life. Born in USA in the 1960s, I guess they were raised in a different mindset, with social stories of the self-made man, the war-effort, the positive value of working, and surely a nerd-focused attitude of being in front of a PC 20 hours a day. I resonate with this dedication, but it can be detrimental if it’s not a balanced philosophy. Find your balance! And find people to work with your balance.
id Programming Principles
Here's the list of id Core Principles during the 90s, time-stamped from the video, together with my notes:
[9:38] No prototypes. Just make the game. Polish as you go. Don’t depend on polish happening later. Always maintain constantly shippable code.
Right from the start, Romero baffles us with a "Don't do prototypes". What! But everyone else advises so! This sure sparked my curiosity. Also what's the deal with this fuzzy "Just make the game"? This principle don't seem to be directly applicable. Let's investigate.
"We knew what the game was, we had it in our minds. We had 10 years of experience. This is a small team of 4 people, large team obviously need planning and prototypes."
Oh ok so the wording was brutal, but it's for their very specific situation. Looking properly, it's mainly why they were so quick. They were capable of working on games without searching for the right game loop, pacing or architecture, because they knew what they were doing. But how?
Their games are very incremental. They create better and better games of the same formula. They made Commander Keen 1, 2, 3 in 3 months, 1 month each! Same with their FPS games, they changed the setting each time to feel new, but refined their tech and design on each new game. This is a smart move to maximize the commercial capacity of their design. See this interview with Chris Zukowski:
"You need to scope way down. A scoping exercise is like the most important thing you can do at the very beginning. [...] It’s the design that matters. It’s not the size."
The devs from id had hard time-constraints on previous projects. They learnt how to scope for these short development times.
There's a lot in this principle, with words like prototype, shippable & polish that can have different meanings. I believe Romero means: no throwaway code & no debug period. A game without bugs, ever. This is some expectation on code quality! The next principles will clarify them.
[11:25] It’s incredibly important that your game can always be run by your team. Bulletproof your engine by providing default upon load failure.
“If you have people developing the game, and the game won’t run, you are paying people to sit around and wait for it to get fixed.”
This principle starts to be better delineated. It seems obvious, almost. It forms part of a working discipline better explained in the next principle.
[16:22] 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.
This one feels like a very concrete code of conduct. I'm already following this principle, when I implement new level art, change materials or when I update a character or UI. Bugs on this part means an unusable level or menu, props without collisions, characters with a broken skeleton, etc. To prevent this, there's no secret: test the game! More on that in the next principle.
In a talk about Wolfenstein 3D postmortem, John Romero says:
"Because we came from the 8 bit era, where we programmed primarily in the assembly language, we couldn't write too much code and not run it, otherwise we'd have a horrific amount of bugs. So we would write 5 or 10 instructions in assembly, run it, and if there was a bug, it was only in this 10 instructions. So our testing loops, our iteration times were really short. So that got us really used to: code a little bit, run it, code a little bit, run it. Anything that's wrong, you'll know immediately and it's not like an hour worth of work that you now have to spend another hour trying to figure out what happened. With that, we ran the code that we made, and when it worked, we gave it to everbody else, and it worked for everbody else. We didn't have a bunch of bugs when we were making games back then."
[15:51] 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.
“No throwing in away over the fence for testers to find and put it to bug database then fix it later. It’s really a wasteful cycle."
This speaks to me. Oh yeah. So the last 3 principles can be summarized by: this great quote from Bob Martin:
"I heard bad code slows us down, so I have an idea: no more bad code!"
In my 12 years of experience, lots of gamedevs I worked with argued that it was a waste of their time to test the game themeselves. While testing, they don't produce features! But, I ask, who's interested in buggy features? Or do they seriously think that they produce bug-free features without testing? Even the demigod of game programming John Carmack tests his code. Do you think your time is more precious than the one from the rest of the team, combined? I can only say it's a pain to be their collegue, having to trip on their bugs, wasting time begging them to fix it so I can work, filing bugs in their database, with reproductible steps and all.
They are times for rapid prototyping, yes. Times for buggy code and placeholders. But they have to be very circumscribed, purposeful and ephemeral.
During Q&A, Romero says:
[1:03:30] “Their game has a lot of bugs because they’re not running the thing they actually coded. Or they run it but, because they coded it, they try not to hurt it. But you need to ruin your code! We played it over and over again. It’s playing it, but trying to mess it up. It was a pride thing to not have anything coming from QA for your code. It was a challenge: you should not have anything wrong with your code. Good nature fun! We had no unit test, we didn’t know what it was. It was easy to debug with hardware breakpoints. We had no manager to talk to people about anything. It was a hive mind, it was a small team. We managed ourselves."
[12:24] Keep your code absolutely simple. Keep looking at your functions and figure out how you can simplify further.
Aiming for bug-free code is easier if the code is simple, so keep the code simple. They are a lot of programming rules of thumb aimed for this: KISS, YAGNI, the Unix philosophy, etc. But it also applies to visual design, animations, workflows! Don't over-complicate your work.
[13:25] Great tools help make great games. Spend as much time on tools as possible.
This principle needs contextualisation. The team at id was aiming for rapid development times, yes, but also for extreme quality. They wanted to stand out. So they had to optimize developer time and machine time.
So they made their own game engine, their own level editor, even their own music file format at one point. They invested time to create tools corresponding to their specific needs. Their tools were made to speed up the development of an otherwise really big undertaking.
But beware! Tool dev time is hard to balance. It's easy to be caught in the chimeric quest of great tools. This principle is valid only if you have a higher principle, urging you to deliver your game.
[17:10] Use a development system that is superior to your target.
“We could make way better tools!”
I first heard this principle from Alan Kay (I believe in this video, not sure, but you can't be wrong watching this talk).
I'm currently thinking that our current machines can do everything. So it is not a matter of upgrading hardware. Our current software, in contrast, is very bad. It is unresponsive, bloated, wasteful of proc cycles, screen estate, ram & disk space. It continues to emulate old ways of doing things, while it could truly use the simulation capacity of the computer. So yes, work on an OS that let you do the best work possible. Work with tools that improve your workflow. And target low hardware, so you can run your game faster, in parallel with your game engine and other tools, on your machine.
I want to read this principle as: use the best software, target low hardware.
Don't fall in the trap of believing that you need a 4GHz, 32Gram beast to make 3D games! Know your game dev history, the PS2 could run Shadow Of The Colossus, an open-world with dynamic range & complex physics with a 0.15GHz, 0.032Gram system. Yes.
[21:35] 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.
It seems to conflict with the 6th principle, "Spend as much time on tools as possible", and the fact that id is known to have started the game engine licencing. They certainly reused code!
But it's simple: don't waste time planning for your future games. You'll be smarter then. Decouple your logic in modules to work quicker and safer on your current game, not for some distant future. It simplifies the 5th principle: "keep your code absolutly simple".
The principle also applies to art assets. It's more obvious because art is "content", but a material library, a set of automation scripts, material functions, file layouts, etc. should all be developed for this game only. Don't worry. You'll be smarter.
So game logic, architecture, frameworks, smart shader libraries, even tools are for this game only. They may be used for the next games. But it's unlikely. You'll see then.
[25:31] Encapsulate functionality to ensure design consistency. This minimizes mistakes and save design time.
Romero is talking about prefabs. Or whatever you call them: Blueprints, Symbols, Assemblies, Nodes... You can't live without prefabs. Prefabs will save you. Prefabs in Prefabs will elevate you. Prefab everything you can.
[28:44] Try to code transparently. Tell your lead and peers exactly how you are going to solve your current task and get feedback and advice. Do not treat programming like each coder is a black box. The project could go off the rails and cause delays.
This also speaks to me, not just for programmers. Artists & designers are also concerned by. Every designer, evey human, in fact. You should not fear feedback. Feedback is a gift. Share your work, your thoughs, crave feedbacks. Be egoless in your work. Feedbacks and iterations are key. See the Design Philosophy by Joshua Mauldin.
[29:00] Programming is a creative art form based in logic. Every programmer is different and will code differently. It’s the output that matters.
“Don’t waste time focusing on a rigid coding style”
This principle needs context. In the following Q&A, Romero explains:
[33:54] “We had no source control. Each programmer owned part of the code, part of the game. We didn’t stomp on each other files. Clear communication, we’re all on the same room, it’s really easy to tell anybody what you’re doing. We never merged.”
So they let each programmer working on their specific files. Coding style was not in a way of merging, because there was no merging.
To stick to this principle, there must be clear separation of responsability, fluid communication and high esteem between game devs. These are worthy goals, reachable in a small experienced team. Romero adds:
[53:44] “In a small team, each person was in charge of a specific thing. Everybody was super respectful of each other. Nobody yelled at each other. It was very professional. We liked being friends with each other. We all hung out with each other. We had the same passion level. Everybody was equally invested. This is critically important.”
Bonus on hiring, from the Q&A session
Hiring the right person is hard. It often is a gambling activity. How id hired? Well, they only hired people they knew for years, people they worked with. And it was a team decision. They erased gambling.
[42:29] "id hired people they already knew and worked with before. They knew they were good at their craft."
[54:01] "Everybody’s involved in the hiring process. There’s no “who’s this?”. We try to find a personality match, somebody that we want to hang out with."
From these eleven principles, I retain some big rules:
- Work transparently with your team, seek feedback.
- Chase all the bugs. Try to ruin your work when testing.
- Keep your game playable at all times.
- Invest dev time in your tools.
- Focus on your current game only.
- Use the best software, target low hardware.
- Make incremental games.
Being able to run the game at all times during production is easier said than done. I worked on teams where we were only able to run the game on fridays. The remaining week, we used debug tools to work on one's part. On other projects, the team waited for milestones deliveries to play the game. That's every 2 months or so. But I also had the chance to work on projects with daily playable builds. And it is something else. They weren't always purged of bugs, but playable. It unlocks so many possibilities, it is the dream.
I am currently getting at the end of a 2.5 years project. It's the longest project I worked on. The team delivers a playable version of this game every 2 months. Every 2 months, we play, we let our relatives play, we gather feedbacks. Then, as a team, we devot one full day thinking about what went right or wrong in our process. Based on this 2 months postmortem, we write our own Core Principles. We adjust previous ones. We build upon our experience. It is of great value. After a full day of talking about what went wrong, rubbing salt in the wounds, and thinking about solutions, everyone in the team is ready to stick to the newly designated principles.
I like core principles, they define a philosophy of work and cement team values. They can be dogmatic, so they need to birth from experience and be concretely defined, tightly delineated. The principles stated by John Romero are sometimes quite vague, sometimes very precise and actionable. They imply a team with lots of experience, proper scoping of projects, and hard dedication.
This speaks to me, because my self-worth comes mainly out of my work. I was raised by values of perfect craftsmanship. But there's a safeguard : it's not a quest of being the best. Nobody can expect to be the best, it is a self-degrading and selfish quest. Just aim for being the best you can. Finish your day with this though: "today, I did a good job".