Game Architecture Revisited Recall: the Game Loop
Total Page:16
File Type:pdf, Size:1020Kb
the gamedesigninitiative at cornell university Lecture 8 Game Architecture Revisited Recall: The Game Loop Receive player input Process player actions Update 60 times/s Process NPC actions Interactions (e.g. physics) = 16.7 ms Cull non-visible objects Transform visible objects Draw Draw to backing buffer Display backing buffer the gamedesigninitiative 2 Architecture Revisited at cornell university The Game Loop Receive player input Process player actions Update Process NPC actions Interactions (e.g. physics) Almost everything is in loop Draw Except asynchronous actions Is enough for simple games How do we organize this loop? Do not want spaghetti code Distribute over programmers the gamedesigninitiative 3 Architecture Revisited at cornell university Model-View-Controller Pattern Controller Calls the • Updates model in methods of response to events • Updates view with model changes Model View • Defines/manages • Displays model the program data to the user/player • Responds to the • Provides interface controller requests for the controller the gamedesigninitiative 4 Architecture Revisited at cornell university The Game Loop and MVC Model: The game state Value of game resources Location of game objects Update View: The draw phase Rendering commands only Major computation in update Draw Controller: The update phase Alters the game state Vast majority of your code the gamedesigninitiative 5 Architecture Revisited at cornell university Application Structure Root Controller Ownership Subcontroller Subcontroller View Model Model Model Collaboration the gamedesigninitiative 6 Architecture Revisited at cornell university Application Structure Root Collaboration Controller Must import class/interface Ownership Instantiates an object OR Calls the objects methods Subcontroller Subcontroller Ownership View Instantiated the object Responsible for disposal Superset of collaboration Model Model Model Collaboration the gamedesigninitiative 7 Architecture Revisited at cornell university Avoid Cyclic Collaboration Controller collaborates with Z Y X collaborates with Y X collaborates with the gamedesigninitiative 8 Architecture Revisited at cornell university Application Structure Root Controller Subcontroller Subcontroller View ? Model Model Model the gamedesigninitiative 9 Architecture Revisited at cornell university CUGL Views: Scene Graphs Root Controller Scene Root Model Node Node Node Node Node Node Model the gamedesigninitiative 10 Architecture Revisited at cornell university CUGL Views: Scene Graphs Root Controller Scene Root Model Node Node Node Node Node Node Model the gamedesigninitiative 11 Architecture Revisited at cornell university CUGL Views: Scene Graphs Root Controller Scene Root Model Node Node Node Node Node Node Model the gamedesigninitiative 12 Architecture Revisited at cornell university Model-Controller Separation (Standard) Model Controller Store/retrieve object data Process user input Limit access (getter/setter) Determine action for input Preserve any invariants Example: mouse, gamepad Only affects this object Call action in the model Implements object logic Complex actions on model Traditional controllers May affect multiple models are “lightweight” Example: attack, collide the gamedesigninitiative 13 Architecture Revisited at cornell university Classic Software Problem: Extensibility Given: Class with some base functionality Might be provided in the language API Might be provided in 3rd party software Goal: Object with additional functionality Classic solution is to subclass original class first Example: Extending GUI widgets (e.g. Swing) But subclassing does not always work… How do you extend a Singleton object? the gamedesigninitiative 14 Architecture Revisited at cornell university Problem with SubclassinG Games have lots of classes Each game entity is different NPC Needs its own functionality (e.g. object methods) Human Orc Want to avoid redundancies Makes code hard to change Common source of bugs Human Human Orc Orc Warrior Archer Warrior Archer Might be tempted to subclass Common behavior in parents Specific behavior in children Redundant Behavior the gamedesigninitiative 15 Architecture Revisited at cornell university Problem with SubclassinG Games have lots of classes Each game entity is different NPC Needs its own functionality (e.g. object methods) Warrior Archer Want to avoid redundancies Makes code hard to change Common source of bugs Human Orc Human Orc Warrior Warrior Archer Archer Might be tempted to subclass Common behavior in parents Specific behavior in children Redundant Behavior the gamedesigninitiative 16 Architecture Revisited at cornell university Model-Controller Separation (Standard) Model NPC Store/retrieve object data Limit access (getter/setter) Preserve any invariants Human Orc Only affects this object Implements object logic Human Human Orc Orc Warrior Archer Warrior Archer Complex actions on model May affect multiple models Example: attack, collide Redundant Behavior the gamedesigninitiative 17 Architecture Revisited at cornell university Model-Controller Separation (Alternate) Model Controller Store/retrieve object data Process game actions Limit access (getter/setter) Determine from input or AI Preserve any invariants Find all objects effected Only affects this object Apply action to objects Process interactions In this case, models Look at current game state are lightweight Look for “triggering” event Apply interaction outcome the gamedesigninitiative 18 Architecture Revisited at cornell university Does Not Completely Solve Problem Code correctness a concern Can I Methods have specifications flee? Must use according to spec Check correctness via typing Find methods in object class Example: orc.flee() Check type of parameters Example: force_to_flee(orc) Logical association with type Even if not part of class the gamedesigninitiative 19 Architecture Revisited at cornell university Issues with the OO ParadiGm Object-oriented programming is very noun-centric All code must be organized into classes Polymorphism determines capability via type OO became popular with traditional MVC pattern Widget libraries are nouns implementing view Data structures (e.g. CS 2110) are all nouns Controllers are not necessarily nouns, but lightweight Games, interactive media break this paradigm View is animation (process) oriented, not widget oriented Actions/capabilities only loosely connected to entities the gamedesigninitiative 20 Architecture Revisited at cornell university ProGramminG and Parts of Speech Classes/Types are Nouns Actions are Verbs Methods have verb names Capability of a game object Method calls are sentences Often just a simple function subject.verb(object) damage(object) subject.verb() collide(object1,object1) Classes related by is-a Relates to objects via can-it Indicates class a subclass of Example: Orc can-it attack Example: String is-a Object Not necessarily tied to class Example: swapping items Objects are class instances the gamedesigninitiative 21 Architecture Revisited at cornell university Duck Typing: Reaction to This Issue “Type” determined by its Java: Names of its methods public boolean equals(Object h) { if (!(h instanceof Person)) { Names of its properties return false;} If it “quacks like a duck” Person ob= (Person)h; Python has this capability return name.equals(ob.name); } hasattr(<object>,<string>) Python: True if object has attribute or method of that name def __eq__(self,ob): if (not (hasattr(ob,'name’)) This has many problems return False Correctness is a nightmare return (self.name == ob.name) the gamedesigninitiative 22 Architecture Revisited at cornell university Duck Typing: Reaction to This Issue “Type” determined by its Java: Names of its methods public boolean equals(Object h) { if (!(h instanceof Person)) { Names of itsWhat properties do we really want? return false;} Capabilities over properties If it “quacks like a duck” Person ob= (Person)h; Python has this capabilityExtend capabilities withoutreturn name.equals (ob.name); necessarily changing} type hasattr(<object>,<string>) Without using newPython: languages True if object has attribute or method ofAgain, that name use softwaredef __patternseq__(self,ob): if (not (hasattr(ob,'name’)) This has many problems return False Correctness is a nightmare return (self.name == ob.name) the gamedesigninitiative 23 Architecture Revisited at cornell university Possible Solution: Decorator Pattern New Functionality OriginalReference to Original Request Decorator Object Functionalitybase object Object the gamedesigninitiative 24 Architecture Revisited at cornell university Java I/O Example InputStream input = System.in; Built-in console input Reader reader = new InputStreamReader(input); Make characters easy to read BufferedReader buffer = new BufferedReader(reader); Read whole line at a time Most of java.io works this way the gamedesigninitiative 25 Architecture Revisited at cornell university Alternate Solution: Delegation Pattern Original Reference to Request Delegate Object delegate Object 1 Forward Request Inversion of the Decorator Pattern the gamedesigninitiative 26 Architecture Revisited at cornell university Alternate Solution: Delegation Pattern Original Reference to Request Delegate Object delegate Object 21 Forward Request Inversion of the Decorator Pattern the gamedesigninitiative 27 Architecture Revisited at cornell university Example: Sort Algorithms public class SortableArray