Transcript Document

GAME 1024: Advanced
Game Programming
Lesson 2: Birth of a Program
By Kain Shin
Quiz
1.
2.
3.
4.
5.
6.
What’s your full name
What does inheritance abuse mean to you?
Fill in the blank for Kain’s catchphrase: “Be a good
___ first, the ___ part will follow”
What is one good reason to have just a single global
game object and no other globals?
What is a blob class?
What is one thing you can do to make the formation
of a blob class less likely?
Bonus C++ Topic: Inheritance Abuse




Makes code harder to manage
Results in a lot of copy-and-paste implementation
Propagates the chance of error to anything that gets affected
by the copy-and-paste mentality
Solutions:




Keep class hierarchies flat and wide instead of tall and thin
Use abstract interface classes with pure virtual functions
Composition: Make member variables generic in nature … i.e.
GetItem(id) instead of GetPants()
Composition: Consider encapsulating algorithms into member
variables that can be changed instead of a virtual function that is
burned into code… i.e. GetAIBehavior() instead of DoAI()
Version Control



Why Use Version Control?
 History!
 Concurrent editing and merge conflicts
 Branches
What are our choices?
 Alienbrain, CVS, Perforce, and lots more
 SourceSafe sucks! Even Microsoft doesn’t use it!
 Perforce is the most likely one you’ll see at work. Atomic
check-ins rock!
Make sure it runs before you check it in, or else, you’ll keep
other programmers from working!
More About Perforce





Go to http://perforce.com and download Perforce on your
home machine. It’s free for up to two users!
Use it with your class project!
After two users, Perforce costs about $800 per user per year,
but that more than pays for itself in programmer time saved at
work
Programmer time is saved because Perforce does atomic
check-ins, meaning if any file in a group does not merge well,
then none of those files get checked in
Perforce stores the history of ascii files as deltas to save
storage space
Useful Programming Utilities


Standard Template Library – for holding a map and list of
objects
 STLPort (http://stlport.org) is an excellent implementation
that includes hash_map, unlike Microsoft’s current
implementation
 std::map and std::list could be very useful for your class
project
Boost (http://boost.org) – handy library of utilities
 smart pointers ward off memory leaks – boost::shared_ptr
Engine/Game Separation



You want to separate game code from Engine code
because a studio’s chance of survival increases if
they can easily reuse tech. Programmer time is one
of the most expensive resources.
If you want to hide source code for a lib, then you
provide only .h files in a folder and none of the cpp
files because the lib takes care of that part.
Middleware providers will do this.
Reuseable Code that is not game-specific should go
in the engine
Organizing your files into a good
directory structure

Deliverable – should be a self-contained directory to run from



Code – Everything in it should be static and not have temp
files written to it when compiling



Contains data and exe
This directory is what you send to non-programmers
The root of code should contain the sln file, but each vcproj file
should live in its own folder. This will make it easy to cleanly move
projects around by folder to other games, such as the engine lib
project
Game code, engine code, and thirdParty code all cleanly separated
from each other
Temp – obj files and other temporary files are written here.
Delete this directory for a clean build
Manager Class Definition


A Manager is a class that manages some
meaningful encapsulated system in the game
such as graphics, audio, physics, input, or AI
Kain wants you to make your manager classes
public member variables of the singleton
game class
Actor Class Definition




An actor is a collection of manifestations from
various game managers (physics, graphics, sound,
etc.) that represent a single dynamic entity within the
game
An actor could be an animating character or it could
be a rock that has some gameplay value
Games do their logic on actors
The actor can be implemented as a class with
pointers to its representation within each manager
class, such as a sound resource, graphics sprite, or
physics object
The Event System


Definition: A system intended to allow communication
between separate game systems that can essentially be
unaware of each other.
Reasons for an event system:




To allow concurrent development on different game systems by
different programmers without stepping on each other’s toes
Decouples the “things happening” from the “things that react to those
happenings”… so a programmer can announce the event without
worrying about reactions to that announcement
Make a codebase much more ready for online/network
implementation
Analogous to the client/server model of computing, except
this is inside one app instead of multiple computers on a
shared network
Event System Details

class cEventManager – the central hub. Analogous to a network server



class cEventID – unique to event type, used as a key for matching
purposes. Analogous to a network packet ID



cEventID& vGetID()const = 0;
class iEventListener – managers will inherit from this abstract class


Constructor: cEventID::cEventID(char*);
Implicit uint conversion: operator unsigned int()const;
EventData – represents everything you’d want to know about the event,
such as position or actorID. Inherit from an iEventData abstract class to
make your own version of data per event


void RegisterListener(pEventListener, eventID)
void TriggerEvent(eventData)
vHandleEvent(eventData) = 0;
*An alternate implementation of an event system is to register function
pointers/functors instead of EventListener objects. The choice is yours.
Listener Analogy for Managers




A manager class listens for events from the rest of
the application, and then acts on the event if it cares
about the event
This is how you can easily get multiple programmers
working in different areas without stepping on each
other.
Doing this right should allow you to easily switch
out middleware or engine tech if you ever had to
(physics, graphics, sound, etc.)
Not all Managers need to be listeners. Use your
judgement.
Puppet Analogy for Actors



An Actor should not change state by itself unless
human or AI input changes it
An actor can be thought of as an inert puppet whose
strings are being pulled by an “ActorController”
class
This example of composition has two benefits


Easy to switch out the controller of any actor to be either
AI-controlled, player-controlled, or even controlled by
different types of AI
You don’t need to make a different version of the actor for
human-controlled versus AI-controlled
Main.cpp suggestion

Encapsulating all game functionality inside the cGame object will make it easier to port your
code to other platforms
int main(int argc, char *argv[])
{
cGame game;
bool playGame;
do
{
playGame = game.Update();
}
while( playGame );
return 1;
}
Game.h Suggestion

The Managers held by cGame do all the work. cGame itself does nothing except channel updates into managers
class cGame
{
public:
static cGame* GetInstance()
{
assert(NULL!=s_pInstance && "a cGame object has not been created yet");
return s_pInstance;
}
cGame();
~cGame();
//returns false when it is time to exit
bool Update();
//public globals...
class cActorManager* m_pActorManager;
class cAudioManager* m_pAudioManager;
class cGraphicsManager* m_pGraphicsManager;
class cInputManager* m_pInputManager;
private:
static cGame* s_pInstance;
Other Classes You’ll Be Writing…




cActorManager – holds an associative container of
cActor objects
cActorController – the puppetmaster to your cActor
cActor – manages a cActorController that can be
switched out during gameplay. Won’t do anything
unless its controller tells it to
cInputManager – translates raw keys into game
actions that will get sent out as events, also allows
input actions to be polled for any logic done inside
Update()
class cActor Suggestions




Remember that an actor merely represents a conglomeration of the separate pieces from each game
system such as sound, graphics, and AI
There is no reason to have an update function for the cActor class unless the actor is animating in some
way (advance frames in the update). Game logic that makes the actor do variable things should be
handled by the puppetmaster of the cActor class, a.k.a. cActorController.
You can have useful queries in this cActor class such as “Is this xy coordinate inside my bounding box?”
A cActor object is only borrowing the representations from other systems, such as GraphicsManager. It
does not actually own those representations. Graphics objects continue to live inside GraphicsManager so
that GraphicsManager can draw its own collection of graphics objects. The cActor will manipulate the
state of its borrowed graphics object as it sees fit. The idea is to architect your cActor class so that all
game logic can take place even if there was no graphics system… or sound system… or physics system…
etc.
cActor::cActor( ??? )
{
m_pGraphicsObject = cGame::GetInstance()->m_pGraphicsManager->CreateGraphicsObject( ??? )
m_pSound = cGame::GetInstance()->m_pAudioManager->CreateSoundBuffer( ??? )
…
}
You Know Enough To Begin…



An Event System that will serve as the
cornerstone of communication between
separate game systems
An Actor system that creates actors and gives
them life in your simulation
A Manager Class for every system you intend
to make for this project. Make managers only
as needed.
Afterthoughts…



“There is no Silver Bullet” and “No plan survives contact with the
enemy”

What you learn in this class are general guidelines and rules of thumb
to keep in mind as you grind through the chaos of actual development
in the real world

Your best weapon against chaos is your own ability to intelligently
adapt to new situations as they arise
Today’s lecture frontloads as much about the class project’s architecture as
possible
You will have more questions. I will expect them. Your real learning
begins as soon as you start on the class project detailed in the syllabus.