Re: what you look for in a coder...
"Colin Fahey" <[email protected]>
| Newsgroups | gmane.games.devel.general |
|---|---|
| Message-ID | <08f701c44d5b$a1b6f020$0301a8c0@pc350> |
Some people believe there is a distinction between the terms "coder"
(or "programmer") and "software engineer". According to this belief,
a "coder" knows a language in detail, corresponding compiler and
associated utilities in detail, and relevant APIs in detail --
whereas a "software engineer" is qualified to design the overall
architecture of an application, and specify the data structures and
algorithms used to accomplish all performance goals. With this
kind of division of labor, the "software engineer" specifies all
modules, data types, methods, and core algorithms (perhaps in
pseudo-code form or in a mathematical form) -- and the "coder"
can accept any part of this specification and implement the part
in a target language, devise local tests, and optimize for speed
or space as requested.
I think such a division of labor could be a recipe for success,
but I also believe it is important to encourage everyone on a
team to think about the overall design as much as possible.
I believe it is critical for a project to have a single master
architect for the software implementation. (There should be
a single master architect for the game design or user experience,
which is a separate dimension.) This master architect should
design the whole application at the highest level and descend
as much as possible to specific implementation.
I also believe it is critical for this master architect to
put all design details in both pseudo-code and diagram form in
an easily-accessed master design document.
As far as indicators of whether or not a person will help finish a
given project, here are my thoughts:
[1] I like the idea of looking at code written by the candidate.
There are different metrics. Does the entire application
run as designed? Does the entire application tolerate wacky
user input and foreign data (which can be faulty or
intentionally designed to cause trouble)? Can one understand
the code readily without the candidate being there to explain
things? Also, consider how much TIME it takes to determine
the behavior of code, or the proper use of a function.
[2] A candidate should be rejected if he or she does not write
comments in code as a matter of habit (even for personal
code), or has any hesitancy to write notes or draw diagrams
about existing code design.
[3] Communication skills are very important. If a candidate is
tense during an interview, how much will change if the
person becomes an employee? I would never assume that a
person would "open up" or be more communicative after
getting past any interview jitters. I would be very
afraid of quiet people.
[4] I think it's important to propose various scenarios to the
candidate in order to determine his or her position on various
principles. Is a candidate willing to just do what he or she
is asked to do? Perhaps things won't reach such a tyrannical
stage in a project, but sometimes circumstances demand just
doing things as requested. Also, would the candidate go along
with something that seemed a little backward or inefficient
if it was a matter already decided upon by the master architect?
I consider myself an extremely good "coder" and "software engineer".
I cheerfully assisted several teams in reaching project goals, and I
was liked by fellow programmers and by other members of the team
(such as artists, managers, hardware engineers, etc).
I only mention those things to support my assertion that the
following opinions are meaningful:
[a] One cause of a project progressing very slowly and causing
frustration for many people on a team is the lack of a
master architect with full authority to approve or deny
any aspect of design or implementation. This master
architect must have the energy to generate a lot of
material, and be willing to adapt to changes, and propagate
changes quickly throughout all documents.
Yes, it's a tough role! But someone has to know the
entire picture. Furthermore, it is this person's responsibility
to make sure this big picture is as evident as possible to
ANYONE, even people outside the software team (such as
business types, artists, etc). If that means creating
documents or chapters specifically to explain the whole
architecture in meaningful and as detailed terms as
possible (without throwing in implementation details),
then that's what the master architect must do.
Nobody on the entire team (except for the master architect)
should wonder about how things fit together. There should
be no doubt. Everyone should know, at all times, where
their work fits in to the overall design -- much like
seeing a "YOU ARE HERE" on a map.
Without a master architect, design arises by group discussion
in high level terms that are often TOO abstract. When it
comes time to connect things together, it can be a disaster.
The master architect is the ONLY person to link the software
team to the business people. The master architect is
responsible for providing sober estimates about the risks
and timelines for implementing any changes to objectives
proposed by business. If the business types do decide to
commit to a change, the master architect is responsible for
fully updating all documents to reflect the new direction
or specification.
Sure, the master architect invites criticism and should take
all comments in to consideration, but people must accept that
this person is in control of THE single, coherent design.
[b] All team members must accept coding guidelines. Variable
names should follow a convention. Compiler warnings should
be treated as errors. Compilers are becoming more strict,
which is terrific, but programmers should be encouraged to
be defensive, almost assuming the worst at every turn, like
every single function call might fail, etc.
Policies should be established about any potentially-
contentious aspect of coding. (When to not use exceptions,
how to allocate memory, use of locals, use of stack,
how to report error conditions, and what language
features are off-limits.)
If a programmer notices that someone else is not following
guidelines, there should be a mechanism for bringing the
code to compliance and punishing the violator. Obviously
the punishment should be in proportion to the violation,
but if there's a guy on the team who routinely fails to
meet guidelines, then there has to be a way to eventually
get the person to shape up or be kicked out.
Too many times there is a person whose code causes many
mysterious bugs that take an inordinate amount of time to
isolate and eliminate -- and in many cases such errors
would have been prevented by simple practices.
But another serious problem arises when a person's code is
too difficult to quickly understand. The ONGOING cost in
terms of time for such code must NOT be underestimated.
There is really no excuse for any piece of code to not
be almost self-evident in its purpose and operation.
Furthermore, the USE of the code should be self-evident,
with any warnings or conditions specified in comments
AND non-source-code documentation.
Consideration should be made for the education level for
all members of the programming team. Unless a language
feature (such as pointers to member functions, or
nested templates, iterators, or whatever) is well-understood
by all members of a team, then one should expect the
wackiest errors possible to arise by the improper use
of such features.
Everyone should set editors to convert tabs to a specified
number of spaces. I'd be tempted to remove the TAB key from
my keyboard (just pop the key cap off) if there wasn't a way
to have it converted to spaces as I typed.
A strict policy should be established for source control
use -- such as: (1) No multiple check-outs (optional);
(2) No check-in unless it compiles without warnings and
the application passes some amount of basic tests;
(3) No files checked out by every Friday at noon, and
no check outs until Monday morning (or something like
that); (4) Clobber all local project directories before
doing a full "get" of all project source code.
These polices, and others, save COUNTLESS hours of
confusion and bugs. So many things go wrong when people
are slack about policies like these. Meanwhile, things
are REALLY SMOOTH when people follow guidelines like
these. On Friday, at lunch, everyone is checked in.
An automated build of all targets can begin. Any bugs
can be fixed before the end of the day or over the
weekend. Voila, every weekend there is a working application
whose entire source tree and data tree can be burned to
CD-ROM or DVD-ROM and copies stored in multiple off-site
locations.
Anyhow, to summarize the many random comments (rants?)
in this section: Standards and policies can dramatically
improve morale by eliminating the events that tend to
drag people down with tedious work that in the end was
really just to fix past mistakes (as opposed to simply
moving forward).
[c] The master architect should devise tests of compliance for
all modules. These tests should not be mistaken for the
actual specification (which is undoubtedly wider in scope),
but the tests should exercise a module in a REALISTIC and
fairly COMPREHENSIVE way. Some tests could be somewhat
contrived to put pressure on critical cases (which would
be ordinarily too rare to expect in a random scenario),
but the focus should be on tests that essentially mimic
actual intended operating conditions.
It is really difficult to overstate the rewarding feeling
that results from achieving goals in a way that can be
established objectively.
I think it is quite possible to have a team of programmers
and other members who are absolutely psyched from the
beginning of a project to the very end -- and I think one
key element (in addition to the concepts in [a] and [b])
is having a full timeline for the project that goes down
to specific tasks with descriptions and tests for completion.
On one project I worked on, such a timeline was established
before development began, and the timeline was based on
sober time estimates for the completion of individual tasks,
broken down in to sub-tasks lasting no more than 3 days.
(Any longer-term task was broken down in to smaller sub-tasks,
and ALL sub tasks had objective tests for completion.)
I was never so excited during a project. It was a challenging
project, but every week, and upon every monthly milestone,
I had objective proof of my work, and I felt good about how
the work fit in to the project. Furthermore, when a task
was completed, it was COMPLETED. Assuming the overall design
is good, completing a task in a conscientious way means people
can build upon the resulting added functionality, and more
and more stuff simply starts working and expanding.
Here's the best part: Assuming preliminary tests show that
technology shouldn't be a bottleneck and a potential cause
for ultimate failure -- everyone knows from the very start
of a well-planned project that the project WILL SUCCEED.
Wow! That's a dangling carrot (i.e., incentive) that only
grows bigger with time! If team members liked the idea when
they joined the team at the beginning, they'll be very happy
and eager to see the product enter the market by the time the
product is entering testing or being shipped.
I've worked on projects in which my coworkers were psyched about
the project, right to release. I've worked on other projects
in which the majority of my coworkers were gloomy about the
future of the project -- often pointing out "obvious" causes
(often unwise management decisions) for the approaching failure
of the project. Regardless of the environment, I make it clear
that my goal is to do what I can to make the project succeed,
because that is the only way for me to make being in an office
worthwhile. Given that making the project succeed is my goal,
I tend to identify not only the critical path in my own work,
but I try to forecast how others are going to screw things up.
Yes, it's a harsh analysis, but that's how I regard most other
programmers: sometimes well-intentioned, but mostly liabilities.
Because there is simply too much work to do on a project
for a single person, I accept that other people will be involved,
and that varying devotion to princples will be present.
That being the case, I take the initiative and find ways of
making sure certain scenarios do not arise. If I see a trend,
and I know that the trend leads to a serious problem, I'll do
something about it, even if the task is mostly in someone
else's domain. It's selfish; I want the project to succeed.
I want to tell people about the project in the future, with
pride -- and I want the product to be on store shelves, or
in the field, being used and appreciated.
If I think fellow coworkers can cheerfully embrace changes to
avoid potential bugs or problems, I'll share my thinking about
the rationale for a specific practice -- otherwise I'll simply handle
the issue myself and move onward. For example, in the old days,
before Java and C#, when it was possible to compile despite
having uninitialized variables with default compiler settings,
I did go through source files and initialize all uninitialized
variables. The positive impact of this simple process was
significant; some mysterious bugs were eliminated, and others
were revealed clearly. I wrote code to scan for excessive
use of stack space (like declaring a big array as a local
variable), and applications to analyze run-time behavior of
certain variables, so they could be studied in detail --
since some bugs involved complex interactions of high-level
entities. Anyhow, modest investments of my time in developing
measures to detect and/or fix many of the error modes of my
coworkers was a defensive strategy that really spared me
from grief.
I know this may sound like an exaggeration -- but I rarely
experience errors in my own code, apart from syntax errors
(mostly missing semicolons, mismatched parentheses, or
mismatched braces) that are immediately caught by the compiler.
Most of my code compiles and works correctly on every compile,
without warnings. Things just work, and it is satisfying to
only move forward. So, given this experience, it is hard
to not regard most coworkers as varying amounts of resistance
to meeting goals. Still, I must add that I have had the
luxury of working with some really great programmers --
people with the same degree of enthusiasm for both the low-level
details and the high-level concepts, and an appreciation for
the need for design and standards. Those people stand out.
Well, I'm sure my boring comments amount to little more than
a poor echo of valuable principles stated in books
like "The Mythical Man-Month" and "Code Complete" (neither
of which I read or own, since I figured I came to similar
conclusions by the time I learned of these books). Whenever
I hear someone paraphrase something from one of these two
books, or a similar book, I have two reactions: (1) The
principle is obvious; and, (2) The principle is 100% true and
is something I have directly observed during various projects
on which I have worked. Perhaps some principles aren't
so obvious and require evidence to support them -- so
reaction (1) is really just me foolishly thinking it was
evident, when in fact it was the brutal experience (i.e., (2))
that made a particular principle seem obvious. Hindsight
is 20/20, so to speak.
Oh, and one final rant: Continuity of employment, or duration
of various projects, should not be given as much consideration
as: Completing projects. Software projects in the games
industry, and in other realms, can have well-defined starting
and finishing points. It often happens that the next project
(say, the next planned video game title, or the next
consumer electronics device, or whatever) doesn't grab one's
interest. I think a gap between projects, after one has
brought a product to completion (i.e., it **shipped**) or
after one has completed a major self-contained component
(essentially a kind of "internal product"), is an okay time to
decide to leave a company. If a person diligently kept
coworkers in the loop about his or her work, and built up
detailed documentation all along, then the departure amounts
to little more than: "We're sorry you won't be with us on
our next adventure. Let us know if you're interested in a
future gig. See you around!" So, the few times a potential
employer pressed for details about exact dates for various
projects, and for explanations about my lengthly gaps in
my employment history, I was really turned off. How can one
make it any clearer on a resume? "I finish projects. You
have a project. If you hire me, I will help you finish the
project." Sure, companies hope to hang on to talent, and I
suppose there is a big fear of technology leaks or loss of
training investment. In such cases I suppose good explanations
of switching jobs are important. It is my opinion, though,
that the most important consideration, especially for a
project-oriented operation, such as a video game company,
or any other business model that involves limited term
productions or cycles, is whether or not a job candidate has
a record of delivering finished products (for projects
that don't fail for reasons well outside the candidate's
control -- such as a publisher dropping the project, or
a robot space alien infestation using mind-control rays to
drive project managers to sabotage the project with crazy
changes in specification...
EMPLOYEE: "Hey, boss! I thought we were
making a web server -- so why all this stuff about
'time portals' and 'anthroplasmic feeding tubes'?!"
BOSS: "Silence, insect! We have endured your species long enough!!"
EMPLOYEE: [Scared] "Uh, I'll just go on my break now..." ).
-------------------------------------------------------
This SF.Net email is sponsored by: GNOME Foundation
Hackers Unite! GUADEC: The world's #1 Open Source Desktop Event.
GNOME Users and Developers European Conference, 28-30th June in Norway
http://2004/guadec.org
_______________________________________________
Gamedevlists-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gamedevlists-general
Archives:
http://sourceforge.net/mailarchive/forum.php?forum_id=557