This is a version of the document I used at Question as its Tech Lead.
Permission to use this on my portfolio was granted by my gracious former business partners.
The purpose of this page is to set expectations for all current and future engineers at this studio for the purpose of hiring as well as performance evaluations.
Use this to map a plan for your career at this studio, and to understand what is expected of others within the engineering department. This is a living document that will evolve as expectations and needs change.
Make features using C++ and Blueprint and whatever other scripting language is required (bat files, python, java/typescript, etc)
Be a partial designer/producer
QA
Shepherd usage of your features for the team
The tldr version of this is that you are able to ace our own interview.
Here's the part from that page that matters:
Code bloat is bad. We don't want to support multiple ways of doing the same thing.
Our long term strategy involves keeping the same people and tech over multiple projects in the hopes that both, the people and the tech, get stronger with each project. This means that in addition to gaining EXP on a project, we hope to also gain code that we won't have to rewrite on the next project, such as flying creature navigation or split screen mode, for example. Sure, we can remember things from the last project, but the time and QA saved by actually having that code from the last project in working condition is a force multiplier.
In addition to code reuse, a lot of design iteration tends to stem from connecting existing features that were not previously connected. We want maximum flexibility between the interactions of all features within the game in order to keep the tech base of the project fertile for systems-driven gameplay. For example, if you start writing your own player class for some special version of a player, then we will have two systems for players that don't talk to each other and may not naturally fit player expectations or benefit from shared dev tools. Using existing code for different usage patterns can create bugs from those shared paths that we will need to discover and hammer out, but that's okay. For us, this inconvenience is worth it for the big picture of maximizing opportunities for systems-driven gameplay and shared dev workflow (such as UI screens).
Bad things that happen when you write your own duplicate system:
We want designers to trust us, and the way we accomplish that is by proving that we understand what they are asking for and deliver output that respects their time.
Do not expect all JIRAs to come from producers. Producers are not your secretaries! Everyone on the team is expected to take some of their time to write a JIRA for either themself or others if they really want to make sure something gets done. If you have to notify somebody on Slack about a thing, a nice way to start is "Just wanted to let you know that I wrote a JIRA for you about ___"
If people stop trusting JIRA as a means of making sure things get done, then they will start bothering you directly through Slack or worse... say things verbally hoping that you heard them. We can't go back to this sort of chaos! Check your JIRAs at least once a week to see if there are any low hanging fruits you can address immediately. Make the rest of the team believe that JIRA is the best way to add bugs and tasks to your plate. Use the various methods of prioritization OR your judgement to figure out what to fix next.
Treat JIRA as your radiation indicator. High levels of radiation will summon a bat signal for intervention from your leads. If your JIRA list is full of obvious bugs, then your leads will reduce the feature load on you to make sure that your focus can shift to bug fixing.
The last thing you want is for a designer to habitually write Blueprint that you have to fix or redo completely.
Prevent this from happening by...
Despite your best efforts, you will likely still end up in situations where you will be fixing BP that you did not write, but the goal here is to minimize these occurrences by just being available.
From the other side, designers will be expected to adhere to Blueprint Authoring Guidelines.
Passing the interview as a gameplay engineer means you are also hybrid designer that plays video games and understands gameplay.
This means that you are expected to...
Not only is this part of being the first to eat your own dog food, but it is also part of a cultural directive to reduce cognitive load on designers as much as possible by not forcing them to remember 1000 different things in order to do their part of the work. If there is something that you own more than they will, then congratulations, you will be the primary tuner of that data unless a formal handoff is acknowledged by both sides.
This can't be stressed enough. You will always be the best QA person for the systems you make. Be the first to eat your own dog food, and don't expect somebody else to tell you when obvious things are broken. Definition of obvious is that you run it once and see right away that it is not doing what it is supposed to do... or it crashes when you do it.
Do not use designers as your first pass QA without their consent!
Your task for any new system is not considered done until documentation exists in the How-To section of Confluence. You don't have to maintain that documentation for every little change unless enough folks benefit from the update, but you do need to make a page that serves as a place to get started, at least.
Any engineer making an engine mod must integrate and maintain our fork of the Unreal Engine so that future integrations of new Unreal versions will not stomp our engine mods.
Strike teams will be formed to serve specific purposes, and then they go away once their reason for existence becomes irrelevant. You may be pulled into one of these, or you might volunteer for one of these. Strikes teams are an opportunity to transcend your discipline and be whatever you need to be to get the job done.
For example, if you were pulled into the "ship party planning" strike team, then your engineering tasks will be scaled back in order to accommodate the time you would be putting into helping plan the ship party. Other types of strike teams that you may get pulled into would be "Metagame Economy" or "Hero Class Powers Systems Design".
Junior programmers are essentially apprentices. They are being paid to learn C++ and Unreal Engine because they have never shipped a product with that technology and will need guidance and mentoring from the more experienced engineers on the team. Junior programmers are a long term investment in the hopes that they will stay with the company long enough to lose the "junior" label.
Junior programmers are NOT expected to complete every task they are assigned. Get as far as you can and then pass the task to somebody else. Your setup work is still a timesaver.
Do not check in anything you are unsure of. This especially includes 3D Math! We do not want designers having to redo their data because your stuff needed to get refactored.
Programmers above the junior level are generally autonomous. They are no longer being paid to learn, but they are not quite senior due to lacking the experience of a full product cycle from start to shipping within the studio's relevant operating language C++. They have never owned a system in C++ from start to shipping. They are also not autonomously proficient within the studio's relevant game engine (Unreal Engine).
This programmer may have expertise in other languages and engines, but in order for the senior label to have meaning in terms of task assignments, the line needs to be drawn with completing a full product cycle in C++ and being autonomously proficient in Unreal Engine in the same way it would be drawn in the other direction if a programmer from Epic got a job in another industry or at some studio that operated in a proprietary engine.
The only exception to this rule is if nobody else in the studio qualifies as senior under the above definition, and we just need to fill a vacuum, which can happen if the studio is doing something that it has never done before.
Programmers are NOT expected to complete every task they are assigned. Get as far as you can and then pass the task to somebody else. Your setup work is still a timesaver.
Do not check in anything you are unsure of. This especially includes 3D Math! We do not want designers having to redo their data because your stuff needed to get refactored.
Senior Engineers are professional self-learners that can do all code and logic in a game by themself, if given enough time.
Tasks given to them generally try to fit the domain of their "T-Shaped" pillar of expertise, but it will not be uncommon to ask a senior engineer to dive headfirst into the unknown for something the studio has never done before.
Sometimes, that "unknown" comes from within, and in this case, the senior engineer is not just a coder waiting for others to "chew their food" for them before tossing it over the fence to the engineering department. At this studio, a Senior Engineer is expected to be a part of the big picture and collaborate with producers and designers to fill in any gaps that need filling in those departments. They help manage chaos by being the adults in the room who give form to the formless so that we won't be afraid of shadows that look big on a wall.
At the senior level, resolving ambiguity and tackling unknowns become part of the job expectation.
If it needs doing and nobody else currently owns it, then the senior programmer becomes the owner of that unknown... reading documentation and talking to stakeholders (producers and designers) as needed to do the following:
A senior engineer understands enough about production and game design to assist in those dimensions as needed.
Senior programmers have shipped a product from start to finish sometime in their career and can step into lead roles, as needed. They have owned some system in a shipping product as its primary architect and go-to expert.
At this level, engineers are expected to be familiar with Unreal's profiling tools and build processes because they no longer have the option of shying away from buildmaster duties if it comes down to them.
In addition to having shipped relevant product, they also exhibit the following qualities:
If we are shipping console builds, then non-junior engineers must be able to run builds on consoles and use console SDK tools to debug unique issues specific to that console as well as be a shepherd for performance optimization and memory usage policing for that console.
Not all engineers want to manage people, some just want to remain an Individual Contributor (IC).
We don't want to lose you if your only career option is to leave and become an IC somewhere else. ICs are involved in technical decisions for the studio as much as managers are. The only difference between an IC and a manager is the "managing people" aspect.
ICs are not expected to manage people or determine salaries, although they may participate in the evaluation process of other engineers.
The highest level that an IC will achieve is Principal Programmer. This position has equal value to the studio as a lead programmer and will be compensated as such.
A Principal Programmer is somebody who is expected to take on Lead duties in the absence of the lead programmer, but otherwise does not manage people. This is the career ladder for engineers who do not want to grow within a management track.
In addition to all the expectations of a Senior Programmer, a Principal Programmer is expected to:
Principal Programmers are only allowed to have one weakness: hoomans... that's why we don't make them people managers.
The manager's job is to make sure humans in the department are utilized in a sustainable manner for the long term health of the studio.
You succeed at being a lead programmer if your engineers are successful at being service providers to designers and artists, and are happy while doing it.
Optics and perception matter: You fail at being a lead programmer if other departments view the tech as unstable or constantly making things that they don't ask for, or if your engineers want to quit because of team conditions.
This position exists in multi-project studios because it gets awkward when a technical director only has one person reporting to them. Until then, the lead programmer of the one project will be assuming these responsibilities.
Tech Director succeeds if all engineers are happy, other disciplines are happy with engineers, and investors are happy with the studio. Tech director fails if any of these are not true.