Search this blog

08 June, 2008

Framerate does matter

Game programming is a difficoult beast. We write performance critical code, we are in an incredibly competitive field, well, you probably know about it. The problems we face are not something unique to games, coding in general poses difficoult engineering problems.

That's mainly because software requirements always change, planning much ahead is difficoult, and also because programs fail deterministically, for bugs, not probabilistically, for stress (as in most other engineering disciplines) and there's no redundancy we can add to be safer (actually redudancy adds problems).

In order to try to cope with those difficoulties, some rules, guidelines and strategies are adopted. The most basic of those is to always have a programs that compiles. That's obvious, if we submit a code change that breaks the build, everyone that gets that change will be unable to work. The next obvious step is to have always not only something that compiles, but that actually works too. So we should always test our code, testing can be automatic (unit tests, stress tests, etc) or done by QA guys (or both).

That's both because bugs can hamper work (if someone has to work on a given subsystem, that has to run correctly), but also because smashing bugs usually requires a lot of time, so we don't want to accumulate them at the end of the project.

Those two rules are pretty obvious, and well understood. On the other hand one thing that I've not always seen enforced, is the importance of the framerate. Framerate drops should be considered worse than bugs. Why? Because bugs can be solved usually without changing the data, while performance issues (as any resource overuse) might end up, and usually will if not solved soon, in changing art assets. I've seen this happening many times, projects reaching their deadlines with framerate problems, having no time to experiment different technical solution, thus ending in removing polygons and scaling textures down.

No surprises, please
The framerate problem is just one examples. In general we want to be flexible to change, but know what to change as soon as possible, and trying anyway to minimize the changes. We want to iterate on the game, always leaving it in a consistent state, respecting its invariants. More, we want to try not to touch a given feature, after it's done. So we iterate in order to add complete features.
Why? Because we don't want to have surprises, we can't make a long term plan (only rough estimates, that we will refine while working), because we know that long term, huge designs fail in computer science, so we like working in small iterations, identifing problems soon and being able to react to them soon. During an iteration, it's possible to fail to deliver a feature in the estimated time, but that's not tragic, if we know it as soon as possible.
The worst error we can make, and I know because I've seen projects doing that, is to code ten incomplete features, being confident that they will need a given amount of time at the end of the project to refine them. In those cases, Murphy's laws come to us and whatever time we reserved for finalling the features will be too small in the best case, in the worst, the coded features will simply be not useful in achieving the desidered result, and in the end, they will be completely escluded, wasting work.

That's why almost everyone in gaming, is using Scrum nowadays. Team is splitted into "vertical slices", groups with enough competencies in every role to complete a feature, features are splitted in tasks, tasks that are planned and re-evaluated in short sprints (usually, two weeks). Each task and each feature is quality tested, and considered done only if approved by the users of that feature (usually desingers or artists). Every company has its own version of this process, but anyway, it's nice, it works.

Slicing a team
What I don't really love about that approach is that every group (rendering, game, artists, etc) is sliced and people are assigned to a given sprint team. That is great for cross-functional communication, that I think it's really the key for a succesful game, especially if you're working with rendering. The collaboration between coders and artists is fundamental, it's the single most important thing to achieve great graphics.
On the other hand, rendering is also about cutting edge technology and algorithms, and Scrum risks to tear apart your rendering team, creating a situation where people don't know what other people are doing, or they just know the tasks, but not the technical details, and so they can't share their ideas. Of course if the owner of a given task needs and asks for help, probably he will get the support he needs. But in many cases, you don't know that you need help, you don't know that another engineer could have a better idea, or that you can have a good one about the problems that other people are going to solve.

Changing attitudes
Unfortunately, this kind of communication is mostly an attitude. If you already have it in your team, even if using Scrum, then it's fine. But what if you don't? You can't force people to speak more, hang together and talk about their work, and share ideas. But you can show the way, trying to be non-intrusive.
Good example helps. You could also think of having a quick, technical "show and tell" meeting, maybe once every week or two, or by request, when someone is working on something interesting or hard, that he wants to speak of, to find ideas. A nice thing is if the leads invites people to speak in those meetings, as the lead should know who is doing what, and how does he thinks to solve a given problem, and if that problem is something worth discussion or not. Another thing that I think it's worth experimenting with is to have "code previews". Code reviews are very useful, they catch bugs, distractions, guideline infrigments etc. But they rarely deal with design, usually it's too late for that, and too difficult, as you're reviewing many lines of changed code, and it can be hard to see the overall design and underlying ideas. In those cases, early reviews might help, and I personally do those when designing big subsystems, asking reviews but specifiying that the code is not complete, and that I just wanted to have feedback on the overall structure of the code.

No comments: