You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<spanname="suffered">bad</span>, the best you could hope to do for them is take
66
62
them out back and put them out of their misery.</p>
67
63
<asidename="suffered">
68
-
69
64
<p>Let’s admit it, most of us are <em>responsible</em> for a few of those.</p>
70
65
</aside>
71
-
72
66
<p>A lucky few have had the opposite experience, a chance to work with beautifully
73
67
designed code. The kind of codebase that feels like a perfectly appointed luxury
74
68
hotel festooned with concierges waiting eagerly on your every whim. What’s the
@@ -93,10 +87,8 @@ <h3><a href="#how-do-you-make-a-change" name="how-do-you-make-a-change">How do y
93
87
you need to <spanname="ocr">load</span> all of the relevant pieces of it into
94
88
your primate brain.</p>
95
89
<asidename="ocr">
96
-
97
90
<p>It’s weird to think that this is literally an OCR process.</p>
98
91
</aside>
99
-
100
92
<p>We tend to gloss over this step, but it’s often the most time-consuming part of
101
93
programming. If you think paging some data from disk into RAM is slow, try
102
94
paging it into a simian cerebrum over a pair of optical nerves.</p>
@@ -109,14 +101,12 @@ <h3><a href="#how-do-you-make-a-change" name="how-do-you-make-a-change">How do y
109
101
<spanname="tests">tests</span> and send it off for code review, you often have
110
102
some cleanup to do.</p>
111
103
<asidename="tests">
112
-
113
104
<p>Did I say “tests”? Oh, yes, I did. It’s hard to write unit tests for some game
114
105
code, but a large fraction of the codebase is perfectly testable.</p>
115
106
<p>I won’t get on a soapbox here, but I’ll ask you to consider doing more automated
116
107
testing if you aren’t already. Don’t you have better things to do than manually
117
108
validate stuff over and over again?</p>
118
109
</aside>
119
-
120
110
<p>You jammed a bit more code into your game, but you don’t want the next person to
121
111
come along to trip over the wrinkles you left throughout the source. Unless the
122
112
change is minor, there’s usually a bit of reorganization to do to make your new
@@ -127,11 +117,9 @@ <h3><a href="#how-do-you-make-a-change" name="how-do-you-make-a-change">How do y
127
117
<p><spanname="life-cycle"></span></p>
128
118
<p><imgsrc="images/architecture-cycle.png" alt="Get problem → Learn code → Code solution → Clean up → and back around to the beginning." /></p>
129
119
<asidename="life-cycle">
130
-
131
120
<p>The fact that there is no escape from that loop is a little alarming now that I
132
121
think about it.</p>
133
122
</aside>
134
-
135
123
<h3><ahref="#how-can-decoupling-help" name="how-can-decoupling-help">How can decoupling help?</a></h3>
136
124
<p>While it isn’t obvious, I think much of software architecture is about that
137
125
learning phase. Loading code into neurons is so painfully slow that it pays to
@@ -165,15 +153,13 @@ <h2><a href="#at-what-cost" name="at-what-cost">At What Cost?</a></h2>
165
153
well and <em>keep</em> it organized throughout the thousands of little changes that
166
154
make up a development cycle.</p>
167
155
<asidename="maintain">
168
-
169
156
<p>The second half of this — maintaining your design — deserves special
170
157
attention. I’ve seen many programs start out beautifully and then die a death of a
171
158
thousand cuts as programmers add “just one tiny little hack” over and over
172
159
again.</p>
173
160
<p>Like gardening, it’s not enough to put in new plants. You must also weed and
174
161
prune.</p>
175
162
</aside>
176
-
177
163
<p>You have to think about which parts of the program should be decoupled and
178
164
introduce abstractions at those points. Likewise, you have to determine where
179
165
extensibility should be engineered in so future changes are easier to make.</p>
@@ -190,12 +176,10 @@ <h2><a href="#at-what-cost" name="at-what-cost">At What Cost?</a></h2>
190
176
modularity doesn’t end up being helpful, it quickly becomes actively harmful.
191
177
After all, it is more code you have to deal with.</p>
192
178
<asidename="yagni">
193
-
194
179
<p>Some folks coined the term “YAGNI” — <ahref="http://en.wikipedia.org/wiki/You_aren't_gonna_need_it">You aren’t gonna need
195
180
it</a> — as a mantra to use
196
181
to fight this urge to speculate about what your future self may want.</p>
197
182
</aside>
198
-
199
183
<p>When people get overzealous about this, you get a codebase whose architecture
200
184
has spiraled out of control. You’ve got interfaces and abstractions everywhere.
201
185
Plug-in systems, abstract base classes, virtual methods galore, and all sorts of
@@ -217,7 +201,6 @@ <h2><a href="#performance-and-speed" name="performance-and-speed">Performance an
217
201
dispatch, interfaces, pointers, messages, and <spanname="templates">other
218
202
mechanisms</span> that all have at least some runtime cost.</p>
219
203
<asidename="templates">
220
-
221
204
<p>One interesting counter-example is templates in C++. Template metaprogramming
222
205
can sometimes give you the abstraction of interfaces without any penalty at
223
206
runtime.</p>
@@ -230,7 +213,6 @@ <h2><a href="#performance-and-speed" name="performance-and-speed">Performance an
230
213
decision of which class to call at <em>compile time</em> when the template is
231
214
instantiated.</p>
232
215
</aside>
233
-
234
216
<p>There’s a reason for this. A lot of software architecture is about making your
235
217
program more flexible. It’s about making it take less effort to change it. That
236
218
means encoding fewer assumptions in the program. You use interfaces so that your
@@ -300,12 +282,10 @@ <h2><a href="#the-good-in-bad-code" name="the-good-in-bad-code">The Good in Bad
300
282
there’s a <em>chance</em> you’ll end up having to keep it around, you may have to
301
283
defensively write it well.</p>
302
284
<asidename="throwaway">
303
-
304
285
<p>One trick to ensuring your prototype code isn’t obliged to become real code is
305
286
to write it in a language different from the one your game uses. That way, you have to
306
287
rewrite it before it can end up in your actual game.</p>
307
288
</aside>
308
-
309
289
<h2><ahref="#striking-a-balance" name="striking-a-balance">Striking a Balance</a></h2>
310
290
<p>We have a few forces in play:</p>
311
291
<ol>
@@ -315,12 +295,10 @@ <h2><a href="#striking-a-balance" name="striking-a-balance">Striking a Balance</
315
295
<li>We want to get today’s features done quickly.</li>
316
296
</ol>
317
297
<asidename="speed">
318
-
319
298
<p>I think it’s interesting that these are all about some kind of speed: our
320
299
long-term development speed, the game’s execution speed, and our short-term
321
300
development speed.</p>
322
301
</aside>
323
-
324
302
<p>These goals are at least partially in opposition. Good architecture improves
325
303
productivity over the long term, but maintaining it means every change requires
326
304
a little more effort to keep things clean.</p>
@@ -342,12 +320,10 @@ <h2><a href="#striking-a-balance" name="striking-a-balance">Striking a Balance</
342
320
that. A field you can master in a week is ultimately boring. You don’t hear of
343
321
someone’s distinguished career in <spanname="ditch">ditch digging</span>.</p>
344
322
<asidename="ditch">
345
-
346
323
<p>Maybe you do; I didn’t research that analogy. For all I know, there could be avid
347
324
ditch digging hobbyists, ditch digging conventions, and a whole subculture
348
325
around it. Who am I to judge?</p>
349
326
</aside>
350
-
351
327
<p>To me, this has much in common with games themselves. A game like chess
352
328
can never be mastered because all of the pieces are so perfectly balanced
353
329
against one another. This means you can spend your life exploring the vast space
0 commit comments