Wednesday, February 15, 2012

Object Oriented Programming

I haven't talked about programming much on here. Which makes me feel like the third word in the title of this blog is a filthy lie. To rectify this, here's some insight into something I recently discovered/learned about.

The Game Object model is a fairly straightforward model to someone with a passing familiarity of Object-Oriented Programming.

First, a primer in Object-Oriented Programming, so you, the reader, can have a passing familiarity with it, so you can see the Game Object model as being fairly straightforward.
 Object-Oriented Programming (OOP) is a programming paradigm that structures code in discrete bundles, a.k.a. objects. Objects as we know them today are a very refined implementation of structures (commonly abbreviated "structs"), that have cleaner and safer access specifications. A struct is nothing more than a collection of data types, and were invented because frequently a group of variables would need to be passed to a function together, and being bundled in a struct made doing so significantly faster (for the programmer) and safer. This bundling idea was refined further, and related functions were wrapped into structs as well.
In addition, the concept of private member variables was introduced, which allowed programmers of a class to disallow other developers from changing important variables that had subtle interactions. For example, a Sprite object that had both a Position and BoundingBox field would want the BoundingBox to be updated whenever the Position was changed, and so it disallows access to those fields except through the Sprite-controlled SetPosition() function, where it can update both without external programmers needing to understand anything about the Sprite more than the atomic action they desired. A Sprite is clearly more complex than a struct, and is distinguished by being referred to as a class.
This control of access is called encapsulation, and proper encapsulation is vital for classes to be able to perform complex operations in a controlled environment. Without the controlled environment that encapsulation provides, important assumptions that the original programmer was making may not actually be true, which leads to unforeseeable errors that can cause programs to fail in wildly unpredictable ways.
But wait, there's more. Classes have another important trick up their sleeve. The second, key aspect to the power of OOP is polymorphism. (I wish I knew a simpler word to use at first before sneaking that one in later, but as far as I know it is what it is.) Classes can inherit other classes, and by doing so share functionality.
One tenet of programming is "don't repeat yourself". This is partly because programmers are lazy, and a good programer avoids writing the same thing twice, and partly because of foreseeing the necessity of change. If copy-pasted code exists in N places in a file, and a bug is found in one of those, what are the chances that that same bug exists in the other N-1 places? (Here's a hint: it's virtually 100%) What if the same fragment of code exists X places in one file, Y places in another, and Z files in a third? What if it also snuck into a fourth file, but nobody on the project is sure which of the 100 project files it might have gone in? And even if the original programmer wrote perfect, bug-free code the first time (they didn't, most likely), what if the requirements change? What if instead of drawing health bars above enemies, a designer decides it would look snazzier underneath? Designs change, and robust code is flexible enough to accommodate these changes easily. Brittle code forces programmers to waste days tracking down obvious fixes. Write robust code, your teammates won't hate you for it.
Inhertiance is a way that one can have multiple discrete objects, without repeating themselves. A class can be declared as deriving itself from, or inheriting, a different class. This shares an appropriate level of functionality, along with all of the base class's member variables and functions. This keeps programmers from repeating themselves when they have a number of similar, yet slightly different, objects. For example, a Sedan and a Truck are different, but both share the functionality of having an Engine, and a StartEngine() function. As such, that similarity can be wrapped into an Automobile class, which both Sedan and Truck inherit.
Polymorphism, then, is a way for a program to access the differences, but in a transparent fashion. Automatic and Manual both derive from Transmission, and they both have a CurrentGear field, and associated functions, but both are interfaced in different ways. The Transmission class, then, declares a virtual function ShiftGearsCheck() that can be overwritten by the subclasses. In the Manual implementation of ShiftGearsCheck(), the transmission looks at the position of the stick to see if it should shift gears, but the Automatic's implementation looks at the current RPM count. Both of these different functions can be accessed through the same ShiftGearsCheck() function, though.
The magic happens because either an Automatic or Manual reference can be stored as a reference to a Transmission-type variable. Any subclass can be referred to through a reference of one of its base classes. If we have a Transmission reference foo, and store a Automatic object in it, then ask foo to ShiftGearsCheck(), foo will reference the appropriate derived function to use (through something called a vtable; you're gonna have to look it up if you're curious because I'm somewhat sketchy on the details).
One of the important consequenses of this is that multiple objects of varying type can be stored in one place. We can keep a list of Automobiles without knowing ahead of time which ones are Sedans, Trucks, or SUVs, and when we ask them to Drive() they will do so in an appropriate way each time.

The Game Object model, then, simply represents every game entity as a class, with a hierarchy such that as much functionality as possible is shared between the classes.

... This is getting entirely too long.
Two-parter!

No comments:

Post a Comment