A designer, a programmer, and a producer walk into a cocktail bar. The barman asks, “What can I get for you?”
The designer says, “Give me something fruity, with an umbrella in. No gin though, it makes me violent.”
The programmer says, “Mix two parts vodka with one part white rum, shake it with ice. Pour it into a glass with strawberry syrup, and top up with sprite. Stick an umbrella in the top and hand it to me.”
The producer, who only came along because they needed a third person to make up the joke, sighs and says, “I’ll have what these guys are having.”
The bartender begins making the drinks, “OK, three Equivalent Expressions, coming up…”
There’s a fundamental difference between the kind of problems that designers and programmers spend their time solving, and as such, I think there’s a difference in their habitual approach to solving problems, and the way they structure and explain their solutions.
Designers are fundamentally interested in the properties of the end result – the visible ‘outer shell’ of the product. They don’t care about the technology inside it, beyond the observable effects (like it being fast enough, not crashing, etc). Their descriptions of the product, and how it should be, are thus all written in terms of these visible properties: which things the player experiences, when and where the player experiences them, and so on.
Programmers, by contrast, are focused on the internals of the product – they are tasked with filling in the gap between the outer shell provided by the designers, and the solid core of functionality provided by the platform. It’s like a translation process – translating high-level game concepts into low-level hardware operations – and so their explanations are in similar terms: which lower-level concepts are in use, how they are combined into large structures, and so on.
Speaking in tongues
This mismatch in modes of thinking requires extra effort to ‘bridge the gap.’ However, it’s not symmetrical.
As we’ve said, the entire focus of a programmer is on constructing these onion-layers of high-level to low-level concepts, composing and decomposing functionality to create the desired result. Connecting concepts between different layers of abstraction is programming. So when a designer talks to a programmer in the highest-level terms, mapping those terms down to the level that the programmer is working at is employing the programmer’s core skill.
The same is not so true for designers. Taking information about the implementation, and deducing from that the visible effects and constraints upon the outer shell, is not actually a part of design. Design is making decisions about the outer shell, within the constraints imposed by the implementation; figuring out what those constraints are is something different. Good designers can do it, of course, but it’s not their core skill.
To put this in slightly more concrete terms: When a designer tells a programmer that he wants a particular enemy to shout something when he sees the player, figuring out the points in the code that will need to be modified to support that is what programming’s all about. But when a programmer tells a designer that he’s added sound hooks to the base enemy class upon selecting a new object of interest, figuring out what this will actually allow the designer to do is not what design’s all about; it’s deciding which enemies should play sounds, and which sounds, that employs their core skill.
Another example, from outside the games industry, is CSS. Of all the designers I know who’ve done work with CSS, there are a few particular parts that they always have trouble with – display, position, and float. Together, these properties are extremely powerful for producing fluid layouts – but using them the way you want requires that you stop thinking like a visual designer, and start thinking like a web page renderer layout system. First this box will be laid out, then this one will be floated to the left inside it, then this other one will be positioned relative to it… it’s a procedural combination of pieces, compensating for the fact that CSS is lacking some useful layout concepts, like built-in support for columns. Knowledge of how to achieve things like an equal-height 3-column layout is passed around as a bit of arcane ‘magic’ that designers just learn and apply, understanding it only in as far as is necessary to use it.
So, I think that when it comes to interfacing design and programming, it would be most efficient to get the programmers to learn to ‘speak designer,’ rather than getting the designers to learn to ‘speak programmer.’ It’s a better match to their core skills, to their habitual modes of thinking.
Designing for designers
Most established programmers already do this in direct communication, I think. When explaining a new system to the design team, you don’t tell them all the class names and algorithms used; you tell them about the features and behaviors that they will use, phrased in their terms, the terms of the end user’s experience. Sure, sometimes you slip up – be it through absent-mindedly forgetting that you’re not talking to fellow programmers, or through enthusiasm about the elegance of what you built, or whatever – but even then, the designers usually speak enough Programmer to follow along.
Where I think this happens less is in tool design.
Internal tools frequently present their concepts and functionality in implementation terms, rather than in end-user-experience terms. Designers get settings with names like ‘Collision Detection mode’ and options like ‘Discrete’ and ‘Continuous,’ which only make sense if you know about how collision detection systems work. So what happens is they learn that they need to set it to ‘Continuous’ for fast-moving objects and ‘Discrete’ for slow-moving objects, and at that point the setting has basically become equivalent to a ‘Movement class’ setting with ‘Fast’ and ‘Slow’ options, except that it includes this extra pointless translation step that needs to be learnt and applied.
It’s not hard to imagine how the tools end up like this. Many of them start out almost as testing rigs for the programmers; the tool is there to allow the programmer to quickly configure and test the system’s features and interactions, so they write it in Programmer, and when they’ve done that it’s technically possible for the designer to set it up however they need it to be, so why make further changes? Yet while it may be technically possible for for the designers to set things up the way they’re needed, it’s not easy, which means that it requires training, takes longer, distracts the designer, and is more error-prone. These costs are often not taken fully into account. The tool has effectively been designed by a programmer, and if that’s OK, why do you have designers on your team at all?
“Well, what if someday there’s an object that is slow-moving but needs Continuous collision detection for some reason nobody can think of right now? Better to keep the flexibility, right? Also, while it might make it easier for the designer to set things up, it makes it harder for the programmer, because now they’ve got to keep remembering that ‘Fast movement mode’ means ‘Continuous collision detection.’ It’s not saved any work, it’s just moved it around.”
Firstly, bear in mind that remembering things like “Fast movement mode is implemented using continuous collision detection” is a programming core skill – just like remembering things such as “CPU Texture reads are implemented using readback-from-video-memory, which is slow, and so should be avoided.” It might be the same amount of work, but programmers have more practice at it.
Secondly, though: simplicity and flexibility aren’t mutually exclusive! Presenting designers with options “phrased in Designer” doesn’t have to mean taking away the options “phrased in Programmer.” The implementation-level options can be hidden away in ‘Advanced Settings’ sections, or in a ‘Programmer View’ mode. The designer-friendly options can be provided as presets – a quick means for designers to automatically set the implementation-level options, while still being able to keep thinking in terms of the end user experience, and without losing the flexibility of tweaking things more directly when required. These are solvable problems!
Programmers and designers have different habits for thinking about problems. When programmers create tools that designers will use, they should present those tools in ‘design language’ – the language of the end-user experience – rather than just exposing the flags and values that the implementation works with. It’s better for them to do that, than for the designers to learn how to manipulate the implementation, because figuring out how to set the implementation for a particular design goal is what the programmers are good at.
Blame @bobvodka if you didn’t think the opening joke worked. If he’s not escaped already, that is.