Skip to content

Commit 56cda29

Browse files
committed
Merge changes from Lauren.
1 parent 03bdc3b commit 56cda29

File tree

4 files changed

+49
-48
lines changed

4 files changed

+49
-48
lines changed

book/double-buffer.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ Method</a> pattern.
317317
</aside>
318318

319319
Actors can also interact with each other, if by "interacting", we mean "they can
320-
slap each other around." When updating, the actor can call `slap()` on another
320+
slap each other around". When updating, the actor can call `slap()` on another
321321
actor to slap it and call `wasSlapped()` to determine if it has been slapped.
322322

323323
The actors need a stage where they can interact, so let's build that:

book/introduction.markdown

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ which was often, we started over from the beginning.
2626
At the back of the stack of pages was a real monster: a program that took up
2727
several dense pages of code. It took a while before we worked up the courage
2828
to even try it, but it was irresistible -- the title above the listing was
29-
"Tunnels and Trolls." We had no idea what it did, but it sounded like a game,
29+
"Tunnels and Trolls". We had no idea what it did, but it sounded like a game,
3030
and what could be cooler than a computer game that you programmed yourself?
3131

3232
We never did get it running, and after a year, we moved out of that classroom.
@@ -50,7 +50,7 @@ good chance this would be a herpetology book instead of a programming one.
5050

5151
At first, the challenge was just getting something on screen. Then, it became
5252
figuring out how to write programs bigger than what would fit in my head. Instead
53-
of just reading about "How to Program in C++," I started trying to find books
53+
of just reading about "How to Program in C++", I started trying to find books
5454
about how to *organize* programs.
5555

5656
Fast-forward several years, and a <span name="friend">friend</span> hands me a
@@ -168,7 +168,7 @@ attempt to do that for software.
168168

169169
</aside>
170170

171-
By calling this book "Game Programming Patterns," I'm not trying to imply that
171+
By calling this book "Game Programming Patterns", I'm not trying to imply that
172172
the Gang of Four's book is <span name="nongames">inapplicable</span> to games.
173173
On the contrary: the [Design Patterns Revisited](design-patterns-revisited.html)
174174
section of this book covers many of the patterns from *Design

book/type-object.markdown

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,25 @@ attack string. When the monster attacks our hero, that text will be shown to the
1919
user somehow. (We don't care how here.)
2020

2121
The designers tell us that monsters come in a variety of different *breeds*,
22-
like "dragon" or "troll." Each breed describes a *kind* of monster that exists
22+
like "dragon" or "troll". Each breed describes a *kind* of monster that exists
2323
in the game, and there can be multiple monsters of the same breed running around
2424
in the dungeon at the same time.
2525

26-
The breed determines a monster's starting health: dragons start off with more
27-
than trolls, making them harder to kill. It also determines the attack string:
26+
The breed determines a monster's starting health -- dragons start off with more
27+
than trolls, making them harder to kill. It also determines the attack string --
2828
all monsters of the same breed attack the same way.
2929

3030
### The typical OOP answer
3131

32-
Given that game design, we fire up our text editor and start coding. According
32+
With that game design in mind, we fire up our text editor and start coding. According
3333
to the design, a dragon <span name="isa">is a</span> kind of monster, a troll is
3434
another kind, and so on with the other breeds. Thinking object-oriented, that
3535
leads us to a `Monster` base class:
3636

3737
<aside name="isa">
3838

3939
This is the so-called "is-a" relationship. In conventional OOP thinking, since a
40-
dragon "is-a" monster, we model that by making Dragon a subclass of Monster. As
40+
dragon "is-a" monster, we model that by making `Dragon` a subclass of `Monster`. As
4141
we'll see, subclassing is only one way of enshrining a conceptual relation like
4242
that into code.
4343

@@ -66,17 +66,17 @@ Exclamation points make everything more exciting!
6666

6767
</aside>
6868

69-
Each class derived from `Monster` passes in the starting health, and overrides
69+
Each class derived from `Monster` passes in the starting health and overrides
7070
`getAttack()` to return the attack string for that breed. Everything works as
71-
expected, and before long we've got our hero running around slaying a variety of
71+
expected, and before long, we've got our hero running around slaying a variety of
7272
beasties. We keep slinging code, and before we know it, we've got dozens of
7373
monster subclasses, from acidic slimes to zombie goats.
7474

7575
Then, strangely, things start to bog down. Our designers ultimately want to have
7676
*hundreds* of breeds, and we find ourselves spending all of our time writing
77-
these little seven line subclasses and recompiling. It gets worse: the designers
77+
these little seven-line subclasses and recompiling. It gets worse -- the designers
7878
want to start tuning the breeds we've already coded. Our formerly productive
79-
work day degenerates to:
79+
workday degenerates to:
8080

8181
1. Get email from designer asking to change health of troll from
8282
48 to 52.
@@ -92,7 +92,7 @@ work day degenerates to:
9292
6. Repeat.
9393

9494
We spend the day frustrated because we've turned into data monkeys. Our
95-
designers are frustrated because it takes them forever just to get a simple
95+
designers are frustrated because it takes them forever to get a simple
9696
number tuned. What we need is the ability to change breed stats without having
9797
to recompile the whole game every time. Even better, we'd like designers to be
9898
able to create and tune breeds without *any* programmer intervention at all.
@@ -103,12 +103,12 @@ At a very high level, the problem we're trying to solve is pretty simple. We
103103
have a bunch of different monsters in the game, and we want to share certain
104104
attributes between them. A horde of monsters are beating on the hero, and we
105105
want some of them to use the same text for their attack. We define that by
106-
saying that all of those monsters are the same "breed," and that the breed
106+
saying that all of those monsters are the same "breed", and that the breed
107107
determines the attack string.
108108

109-
We decided to implement this concept using inheritance, since it lines up with
110-
our intuition of classes: A dragon is a monster, and each dragon in the game is
111-
an instance of this dragon "class." Defining each breed as a subclass of an
109+
We decided to implement this concept using inheritance since it lines up with
110+
our intuition of classes. A dragon is a monster, and each dragon in the game is
111+
an instance of this dragon "class". Defining each breed as a subclass of an
112112
abstract base `Monster` class, and having each monster in the game be an
113113
instance of that derived breed class mirrors that. We end up with a class
114114
hierarchy like this:
@@ -152,16 +152,16 @@ same breed: starting health and the attack string.
152152
To associate monsters with breeds, we give each `Monster` instance a reference
153153
to a `Breed` object containing the information for that breed. To get the attack
154154
string, a monster just calls a method on its breed. The `Breed` class
155-
essentially defines a monster's "type." Each breed instance is an *object* that
155+
essentially defines a monster's "type". Each breed instance is an *object* that
156156
represents a different conceptual *type*, hence the name of the pattern: Type
157157
Object.
158158

159159
What's especially powerful about this pattern is that now we can define new
160-
*types* of things without complicating the codebase at all: we've essentially
160+
*types* of things without complicating the codebase at all. We've essentially
161161
lifted a portion of the type system out of the hard-coded class hierarchy into
162162
data we can define at runtime.
163163

164-
We can create hundreds of different breeds just by instantiating more instances
164+
We can create hundreds of different breeds by instantiating more instances
165165
of `Breed` with different values. If we create breeds by initializing them from
166166
data read from some configuration file, we have the ability to define new types
167167
of monsters completely in data. So easy, a designer could do it!
@@ -170,7 +170,7 @@ of monsters completely in data. So easy, a designer could do it!
170170

171171
Define a **type object** class and a **typed object** class. Each type object
172172
instance represents a different logical type. Each typed object stores a
173-
**reference to the type object that describes its type.**
173+
**reference to the type object that describes its type**.
174174

175175
Instance-specific data is stored in the typed object instance, and data or
176176
behavior that should be shared across all instances of the same conceptual type
@@ -183,11 +183,11 @@ having a fixed set of hard-coded subclasses.
183183

184184
This pattern is useful anytime you need to define a variety of different "kinds"
185185
of things, but baking the kinds into your language's type system is too rigid.
186-
In particular, it's useful when either of these are true:
186+
In particular, it's useful when either of these is true:
187187

188188
* You don't know what types you will need up front. (For example, what if our
189189
game needed to support downloading content that contained new breeds of
190-
monster?)
190+
monsters?)
191191

192192
* You want to be able to modify or add new types without having to recompile
193193
or change code.
@@ -207,18 +207,18 @@ automatically. The data that defines each class is automatically compiled into
207207
the static memory segment of the executable and just works.
208208

209209
With the Type Object pattern, we are now responsible for managing not only our
210-
monsters in memory, but also their *types*: we have to make sure all of the
210+
monsters in memory, but also their *types* -- we have to make sure all of the
211211
breed objects are instantiated and kept in memory as long as our monsters need
212212
them. Whenever we create a new monster, it's up to us to ensure that it's
213213
correctly initialized with a reference to a valid breed.
214214

215215
We've freed ourselves from some of the limitations of the compiler, but the cost
216-
is we have to re-implement some of what it used to be doing for us.
216+
is that we have to re-implement some of what it used to be doing for us.
217217

218218
<aside name="vtable">
219219

220220
Under the hood, C++ virtual methods are implemented using something called a
221-
"virtual function table", or just "vtable." A vtable is a simple struct
221+
"virtual function table", or just "vtable". A vtable is a simple `struct`
222222
containing a set of function pointers, one for each virtual method in a class.
223223
There is one vtable in memory for each class. Each instance of a class has a
224224
pointer to the vtable for its class.
@@ -235,7 +235,7 @@ pattern applied to C, handled automatically by the compiler.
235235

236236
### It's harder to define *behavior* for each type
237237

238-
With subclassing, you can override a method and do whatever you want to:
238+
With subclassing, you can override a method and do whatever you want to --
239239
calculate values procedurally, call other code, etc. The sky is the limit. We
240240
could define a monster subclass whose attack string changed based on the phase
241241
of the moon if we wanted to. (Handy for werewolves, I suppose.)
@@ -251,12 +251,12 @@ monster needed to use different AI algorithms, using this pattern becomes more
251251
challenging.
252252

253253
There are a couple of ways we can get around this limitation. A simple solution
254-
is to have a fixed set of pre-defined behaviors, and then use data in the type
254+
is to have a fixed set of pre-defined behaviors and then use data in the type
255255
object to simply *select* one of them. For example, let's say our monster AI
256256
will always be either "stand still", "chase hero", or "whimper and cower in
257257
fear" (hey, they can't all be mighty dragons). We can define <span
258-
name="fn">functions</span> to implement each of those behaviors. Then we can
259-
associate an AI algorithm with a breed by simply having it store a pointer to
258+
name="fn">functions</span> to implement each of those behaviors. Then, we can
259+
associate an AI algorithm with a breed by having it store a pointer to
260260
the appropriate function.
261261

262262
<aside name="fn">
@@ -268,7 +268,7 @@ type objects.
268268

269269
Another more powerful solution is to actually support defining behavior
270270
completely in <span name="data">data</span>. The <a class="gof-pattern"
271-
href="http://c2.com/cgi-bin/wiki?InterpreterPattern">Interpreter</a>, and <a
271+
href="http://c2.com/cgi-bin/wiki?InterpreterPattern">Interpreter</a> and <a
272272
class="pattern" href="bytecode.html">Bytecode</a> patterns both let us build
273273
objects that represent behavior. If we read in a data file and use that to
274274
create a data structure for one of these patterns, we've moved the behavior's
@@ -314,7 +314,7 @@ here on out is bonus.
314314

315315
With what we have now, we construct a monster directly and are responsible for
316316
passing in its breed. This is a bit backwards from how regular objects are
317-
instantiated in most OOP languages: we don't usually allocate a blank chunk of
317+
instantiated in most OOP languages -- we don't usually allocate a blank chunk of
318318
memory and then *give* it its class. Instead, we call a constructor function on
319319
the class itself, and it's responsible for giving us a new instance.
320320

@@ -347,7 +347,7 @@ implementation, creating a monster looked like:
347347
There's another minor difference here. Because the sample code is in C++, we can
348348
use a handy little feature: *friend classes.*
349349

350-
We've made `Monster`&rsquo;s constructor private which prevents anyone from
350+
We've made `Monster`&rsquo;s constructor private, which prevents anyone from
351351
calling it directly. Friend classes sidestep that restriction so `Breed` can
352352
still access it. This means the *only* way to create monsters is by going
353353
through `newMonster()`.
@@ -394,7 +394,7 @@ Just like we did with our original OOP solution, we can solve this using
394394
inheritance. Only, this time, instead of using our language's inheritance
395395
mechanism, we'll implement it ourselves within our type objects.
396396

397-
To keep things simple, we'll just support single inheritance. In the same way
397+
To keep things simple, we'll only support single inheritance. In the same way
398398
that a class can have a parent base class, we'll allow a breed to have a parent
399399
breed:
400400

@@ -404,13 +404,13 @@ When we construct a breed, we give it a parent that it inherits from. We can
404404
pass in `NULL` for a base breed that has no ancestors.
405405

406406
To make this useful, a child breed needs to control which attributes are
407-
inherited from its parent and which it overrides and specifies itself. For our
407+
inherited from its parent and which attributes it overrides and specifies itself. For our
408408
example system, we'll say that a breed overrides the monster's health by having
409-
a non-zero value, and overrides the attack by having a non-`NULL` string.
409+
a non-zero value and overrides the attack by having a non-`NULL` string.
410410
Otherwise, the attribute will be inherited from its parent.
411411

412412
There are two ways we can implement this. One is to handle the delegation
413-
dynamically, every time the attribute is requested, like this:
413+
dynamically every time the attribute is requested, like this:
414414

415415
^code 10
416416

@@ -465,9 +465,9 @@ fields, the `Troll Archer` and `Troll Wizard` breeds inherit from the base
465465
Since both of them have zero for their health, they'll inherit it from the base
466466
`Troll` breed instead. This means now our designer can tune the health in
467467
`Troll` and all three breeds will be updated. As the number of breeds and the
468-
number of different attributes each breed has increases, this can be a big
468+
number of different attributes each breed has increase, this can be a big
469469
time-saver. Now, with a pretty small chunk of code, we have an open-ended system
470-
that puts control in our designer's hands and makes the best use of their time.
470+
that puts control in our designers' hands and makes the best use of their time.
471471
Meanwhile, we can get back to coding other features.
472472

473473
## Design Decisions
@@ -483,14 +483,14 @@ able to easily understand it. The simpler we can make it, the more usable it
483483
will be. So what we'll cover here is the well-trodden design space, and we'll
484484
leave the far reaches for the academics and explorers.
485485

486-
### Is the Type Object encapsulated or exposed?
486+
### Is the type object encapsulated or exposed?
487487

488488
In our sample implementation, `Monster` has a reference to a breed, but it
489489
doesn't publicly expose it. Outside code can't get directly at the monster's
490490
breed. From the codebase's perspective, monsters are essentially typeless, and
491491
the fact that they have breeds is an implementation detail.
492492

493-
We can easily change this and allow Monster to return its Breed:
493+
We can easily change this and allow `Monster` to return its `Breed`:
494494

495495
<span name="null"></span>
496496

@@ -505,7 +505,7 @@ never be returned.
505505
</aside>
506506

507507
Doing this changes the design of `Monster`. The fact that all monsters have
508-
breeds is now a publicly-visible part of its API. There are benefits with either
508+
breeds is now a publicly visible part of its API. There are benefits with either
509509
choice.
510510

511511
* **If the type object is encapsulated:**
@@ -540,7 +540,7 @@ choice.
540540
get to breeds directly, they wouldn't be able to call it.
541541

542542
* *The type object is now part of the object's public API.* In general,
543-
narrow interfaces are easier to maintain than wide ones: the less you
543+
narrow interfaces are easier to maintain than wide ones -- the less you
544544
expose to the rest of the codebase, the less complexity and maintenance
545545
you have to deal with. By exposing the type object, we widen the
546546
object's API to include everything the type object provides.
@@ -596,7 +596,7 @@ zombie one.
596596
* *There's less object creation.* In our example, if the type can't
597597
change, we'll be forced to burn CPU cycles creating a new zombie
598598
monster, copying over any attributes from the original monster that need
599-
to be preserved, and then deleting it. If we can simply change the type,
599+
to be preserved, and then deleting it. If we can change the type,
600600
all that work gets replaced by a simple assignment.
601601

602602
* *We need to be careful that assumptions are met.* There's a fairly tight
@@ -617,7 +617,7 @@ zombie one.
617617
that needs sharing between your type objects, why make things hard on
618618
yourself?
619619

620-
* *Can lead to duplicated effort.* I've yet to see an authoring system
620+
* *It can lead to duplicated effort.* I've yet to see an authoring system
621621
where designers *didn't* want some kind of inheritance. When you've got
622622
fifty different kinds of elves, having to tune their health by changing
623623
the same number in fifty different places *sucks*.
@@ -633,8 +633,8 @@ zombie one.
633633

634634
* *Looking up attributes is slower.* To get a given piece of data from a
635635
type object, we may now need to walk up the inheritance chain to find
636-
the type that ultimately decides the value. If we're in performance
637-
critical code, we may not want to spend time on this.
636+
the type that ultimately decides the value. If we're in
637+
performance-critical code, we may not want to spend time on this.
638638

639639
* **Multiple inheritance:**
640640

note/style.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- Italics for emphasis.
1717
- Quote block used for sentence long quotes but double quote ("") used for references what other people call something e.g. GoF call this the "subject".
1818
- Colon precedes block quote.
19+
- Punctuation appears outside quotation marks unless the punctuation is part of the quoted matter (logical punctuation).
1920
- Items in a numbered list are complete sentences with starting caps and ending period.
2021
- Use "Naïve" instead of "Naive".
2122
- Use smart quotes.

0 commit comments

Comments
 (0)