1 Guidelines for writing Empire code
4 Remarks from Dave Pare:
6 And now, a few editorial remarks on my views on Good Techniques for
7 Modifying Existing Software:
9 My safari through the hot and bug-ridden jungle that Empire has become
10 has given me some new insights on the modification of large software
11 packages. My adventure has prompted me to propose some simple coding
12 guidelines for those dreaming of hacking on the code:
14 1) Be invisible. When you make a change, think not about marking your
15 place in history, or about showing off how much nicer your two-space
16 tabs are than those old, icky eight-space tabs that the stupid empire
17 hackers of old used, but think instead about the asethetics of the whole.
18 The resulting lines of code should flow smoothly from the beginning of the
19 procedure to the end. Empire is 60,000 lines of code. If you're the
20 general case, you're only changing fifty lines, so be aware of that.
22 2) Procedurize. If you find yourself in a triple-nested loop, or a five
23 hundred line procedure, perhaps it's because you need to split some of
24 that code off into a procedure. In general, if you've got more than two
25 levels of tabs (or indentations), or more than one or two major loops in
26 a procedure, something may well be amiss.
29 Sasha Mikheev on indentation:
31 The empire indentation style can be achived by using
32 indent -orig -i8 foo.c
34 or in old c-mode emacs (versions before 19.29):
36 (setq c-indent-level 8)
37 (setq c-continued-statement-offset 8)
38 (setq c-argdecl-indent 8)
39 (setq c-brace-offset -8)
40 (setq c-label-offset -8)
43 Further comments by Ken Stevens:
46 The only variables which should be global are constants. If you write
47 a routine which changes a global variable, then you will corrupt the
48 data when two different players run that routine at the same time.
56 Should be rewritten as:
62 AIX has different conventions for signed chars, and IRIX requires the
63 /* comments */ after #endif.
66 Cut-and-Paste coding is by far the biggest problem that the current
67 Empire suffers from. This is how cut-and-paste coding happens. Joe
68 Shmuck decides that he wants to add a new function to the server. So
69 he goes hunting through the server to find some already existing code
70 which does something similar to what he wants to do. This is good.
71 You should always write new code to imitate old code. What is bad is
72 when Joe Shmuck decides to simply "copy" 200 lines of code from the old
73 function into his new function, and then just change a couple of
74 little things here and there to suit his needs. This method, known as
75 Cut-and-Paste coding is the fastest and easiest way to code. However,
76 it results in a server that is impossible to maintain. What Joe
77 _should_ have done, is "move" the 200 lines of code into a new _third_
78 function which the first two both call. This is called writing a
79 "general solution" to handle both cases. Most of my work in the
80 Empire2 project consisted in cleaning up after a bonch of Joe Shmucks.
81 I took repeated code and "consolidated" it into general function
85 Just to add to Dave's "Be Invisible" motto, I'd like to give a little
86 example to illustrate some basic do's and don'ts for coding style:
88 The following function has bad style:
90 double att_combat_eff(com,own)
95 if(com->type==EF_SECTOR)
99 str=com->sct_dcp->d_ostr;
101 str=com->sct_dcp->d_dstr;eff=2.0+(str-2.0)*eff;
102 }else if(com->type==EF_SHIP&&com->own!=own)
103 eff=(1.0+com->shp_mcp->m_armor/100.0);
106 Here is the same function written with "good" style:
109 att_combat_eff(com, own)
116 if (com->type == EF_SECTOR) {
117 eff = com->eff / 100.0;
119 str = com->sct_dcp->d_ostr;
121 str = com->sct_dcp->d_dstr;
122 eff = 2.0 + (str - 2.0) * eff;
123 } else if (com->type == EF_SHIP && com->own != own)
124 eff = (1.0 + com->shp_mcp->m_armor / 100.0);
129 These are all the things I fixed when changing the bad to the good:
130 - Function names should always start a new line (so you can search for them)
131 - There should always be a space after a ","
132 - Function arguments should be indented 8 spaces
133 - There should always be a tab after a type declaration
134 - Opening function bracket should be on a line by itself
135 - Indentation should be 8 spaces
136 - There should always be a space on both sides of every operator
137 - There should always be a space after if, for, while, switch
138 - The opening bracket should be on the same line as the if
139 - There should always be a space on either side of a {
140 - There should always be a new line after a ;
141 - The closing function bracket should be on a line by itself