The Next Stage
by Chris "Kiwidog" Hargrove
Download this week's code files:cotc11src.zip (113k)
Be sure to read the license agreement before using the code.
"What we call 'Progress' is the exchange of one nuisance for another nuisance." - Henry Havelock Ellis
Back again! It's hard to think up an appropriate beginning for this week's article, since the discussion is a bit broad, so I'm just going to skip the intro this time. :)
First, the code. This week's codebase contains a revised and more complete video layer, with a added functions for video mode retrieval, arbitrary surface images (for sprites etc), image resource loading, and other odds and ends. While almost all of the work is still being done in vid_win, a vid_main interface has now been added above it (making the layer available for "public use", so to speak). The video layer is one of those things that's never entirely "done" until the project is over (actually that's pretty much the case for all the rest of the code, too, and you've probably noticed me patching up bits and pieces of the overall codebase here and there), but it'll serve its purpose for now. It will be updated as time goes along, primarily with the addition of some convenience functions (like line drawing) and image priorities for video memory / system memory negotiation. For the moment, all the surfaces are being allocated in system memory, and it will stay this way until the project starts using more images and their priorities become more well-defined. Also, the dedicated "off-screen frame buffer" surface has been eliminated, since it's no longer necessary with the addition of arbitrary surface support (you can create an offscreen frame buffer at will just by loading an empty image and locking it). So while the subsystem still has some work left to be done, the important stuff is there and usable for our immediate needs.
I'm not quite sure why I procrastinated on these additions for so long, although it's likely just due to the fact that I don't like working with DirectDraw. The thing with DirectDraw that gives me a sinking feeling time every time I code for it is not writing the code itself or anything like that (that's usually simple enough), it's the uncertainty. Unlike DirectInput, DirectSound, and a few of the other "simpler" DirectX APIs, DirectDraw has a lot of usage ambiguities that make me feel like I'm always missing something that I should be doing, whether it be another performance-gaining step, or some other capabilities flag I should be checking for compatibility, or whatever. I seriously doubt I'm alone in this feeling. Unfortunately DirectDraw is a necessary evil, so there's no real way around it, you just have to dive in and hope for the best.
Anyway, I'm rambling. The point is, the video layer code is finally getting some rather overdue improvements. It's not "finished", but the rest can be added at the project's leisure. Anyway, go check out vid_main.* and vid_win.* if you're interested.
Time for a change of subject. Since I don't talk about code specifics much anymore in the article text, I'm going to take the rest of this space to talk about what the title vaguely referred to as "the next stage".
And what do you mean by "the next stage"?
Not the next stage of this game project, so to speak (although I'll be talking about that briefly at the end of the article), but a bit of a more philosophical programming topic.
I'm talking about the stages of being a programmer. I've had discussions relating to this with many of my colleagues on and off over the past several years, and it seemed like something worth talking about. If you're not the introspective type, then you should stop reading now, because this issue requires quite a bit of introspection.
Psychologists often denote various levels of human development by "stages", such as unicentric, concrete, and so forth. Each stage is marked with certain common characteristics (like the ability to recognize more than one dimension of space, the ability to focus on others more than on oneself, and so forth). While careers have many different forms of personal measurement, such as one's number of years of experience, I found myself wondering if there were similar "stages" of growth for programmers. All too often I see (and end up using) terms like "beginner", "intermediate", "expert", and such, but they really don't mean anything. There have to be some more well-defined characteristics that emerge as a programmer progresses.
This issue didn't really come up for me until sometime after I had left Raven. I could tell I had grown as a programmer between the time I joined the company and the time I left it, but I couldn't really explain how. At some time during my experience there, something in my head "clicked" that I couldn't describe. I was talking to a friend sometime afterward (who was also an employee there at the time), and he could relate to the feeling, which he'd had at one point as well. He could only describe it as "finding your code style". Although that term didn't quite grasp what I was thinking, it did make me wonder. Sometime afterward I began thinking about this "stages of a programmer" thing, and talked about it with a couple of my current coworkers here. Then I realized that the "click" I felt was me hitting one of those stages, and I started thinking about the other stages I've inadvertantly hit over the past few years... and which ones still remain.
I'm going to give an overview of some of the stages I've identified based on programmers I've encountered. While these aren't scientific by any means (and while they're unfortunately slanted towards a game programming angle), that's not the point. The point is, maybe some of you readers out there can relate to some of these stages. If so, maybe a point of view like this might help you find out some new things about yourself as a programmer, and perhaps even help you, on whatever road you wish to travel.
Oh, and be aware that I'm just making up these names.
Stage 1 - Fundamental. A programmer's first exposure to programming, learning basic logical and structural concepts, and so forth. Here one is capable of writing programs to solve certain problems, such as those assigned in school or with similar complexity. Programmers at this stage often don't have any real "drive" to program, but do so out of necessity or supplemental desires (i.e. it'll help them find a job).
Stage 2 - Exploratory. A large stage beginning with a realization that there are more possibilities in programming than once thought, usually marking the start of a programmer's motivational drive. Programmers here begin learning a wide variety of programming topics, languages, and paradigms, often in a random and self-taught order based on current interest and any information accessible.
Stage 3 - Concrete. A second "exploratory" stage where the programmer becomes comfortable with his/her current knowledge and methods of acquiring new information. Research mechanisms become more disciplined, and the programmer finds themself answering more questions amongst peers than asking them.
Stage 4 - Analytical. The programmer begins focusing less on implementation details of specific topics and more on problem analysis, including self-analysis of one's coding conventions and design methodologies. Large-scale construction issues become dominant over smaller-scale programming problems, which can now be solved as needed.
Stage 5 - Holistic. Programmers at this stage attempt to see projects from all angles, before and during construction. Software engineering decisions become disciplined, and a project's implementation becomes a mere manifestation of its design, not the controlling force. Construction details and related problems are increasingly seen before they happen, with the programmer capable of focusing on multiple levels of a design simultaneously.
Stage 6 - Dynamic. The programmer ceases to consider project design as the primary programming factor, and begins to focus on design of a design itself, turning the concept of a project into a completely abstract conceptual entity.
Stage 7 - ?
Does this stage breakdown even apply at all? I think it does, to some extent. So where does everyone fit on this? A whole lot of people (when I say "people" in this case, I mean programmers) never leave the Fundamental stage, and to their credit, many don't need to. For those out there who only need to program to perform a particular (well-defined) job, it's perfectly suitable.
Stages 2 and 3 are probably the most populated out there, and that's especially true for game programmers (most notably hobbyists). Think about all the programming web sites you've seen, how many message boards you've come across, all the questions that get asked in programming IRC channels, etc.
Now getting from Stage 3 to Stage 4 is one of the more tricky ones, at least it was for me. I now believe my "click" I mentioned previously was this particular transition. Everyone has these "clicks" when going from one stage to the next, but some are more noticable than others. This was one of the more noticable ones for me, and for most of the programmers I've talked to who've come along a similar path. One of the reasons getting to Stage 4 is often so difficult (and so noticable in hindsight) is because Stage 3 is extremely cocky. Since the Concrete stage is about as high as a large number of programmers ever need to go (or so they think), and since those in that stage are now answering more questions to the public than they openly ask, it feels like a very "knowledgeable" place to be. After all that a programmer has learned by that point, it becomes easy for them to assume they know all they need to in order to do anything they want. That level of comfort ends up being a hidden hurdle that many folks never even see, let alone get past. And that's the trick. If you're a hobbyist game programmer looking to get a game industry programming job, take this issue into consideration immediately.
Once you get to Stage 4, the world of programming changes dramatically. Projects become less about variables, functions, and structures and more about modules and interfaces. Getting people to this stage has indirectly been one of the focal points of these articles.
Going from Stage 4 to Stage 5 isn't as much of a click as it is a smooth transition. The downside is that this transition is an extremely dangerous place to be from a project design standpoint. While I believe anyone wanting to code in the game industry should be comfortably at Stage 4 at least, I wouldn't make someone lead programmer on a project until they were firmly in Stage 5, lest the project suffer.
Without sounding too arrogant, I'd like to think of myself as now happily sitting in Stage 5, working towards Stage 6. I'm not there yet, although I'm aware of many professors and other academic figures who are, and I watch their work intently. A portion of "Stage 6 thought" has already started to take a well-known form via "design patterns", reusable pieces of software design and architecture that are purely abstract in nature (and usable by programmers at all stages). While design patterns are a step in the right direction, they're based more on the "mining" of existing architectures rather than the creation of entirely new design concepts, which I believe is the next step.
And Stage 7? That's why I leave it as a question mark; I have no idea where Stage 7 and beyond may lead. But I'm eager to find out, and hopefully so are some of you. Software engineering has progressed by leaps and bounds over the past several decades, but it's nowhere near where it's going to be taking us over the years to come.
So, at what stage do you sit right now? Where do you want to be sitting next year? And after that? The decision is largely introspective, but give it some thought... it may affect you more than you realize.
As For The Project
So what about the "next stage" for this game? Last time I asked people what specific topics they'd like to see covered during this series, and I'm still considering which ones to choose (so keep the suggestions coming). Regardless, game control logic and networking are going to become major considerations, so we'll be starting on those next. The next article will cover creating code to support game entities (or "actors"), from a broad architectural point of view. This will tie very closely into the networking code, the kernel of which will be written shortly afterward. While much of the code for these two topics is still project-independent, a few game logic choices will require decisions regarding the game project itself, and I'll be talking about those as we go. Over the next several articles the project will start to congeal into a recognizable target. The end of the road is in sight. :)
Until next time,
- Chris"Kiwidog" Hargrove is a programmer at 3D Realms Entertainment working on Duke Nukem Forever.
Code on the Cob is © 1998 Chris Hargrove.
Reprinted with permission.