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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.