610 likes | 864 Views
Pipeline Design. François Paradis Jonathan T-Delorme Ubisoft – Québec Studio – Onyx Team Featuring Scott Pilgrim vs. The World. A non-intrusive data driven architecture. WORLD 1 INTRODUCTION. The Plan. WORLD 3 DATA INHERITANCE. WORLD 2 REFLECTION. WORLD 4 EDITOR EXPERIENCE.
E N D
Pipeline Design François Paradis Jonathan T-Delorme Ubisoft – Québec Studio – Onyx Team Featuring Scott Pilgrim vs. The World A non-intrusive data driven architecture
WORLD 1 INTRODUCTION The Plan WORLD 3 DATA INHERITANCE WORLD 2 REFLECTION WORLD 4 EDITOR EXPERIENCE
Our Job classGameObject { /* Game Logic ... */ Vector2position; Animation* animation; }; classHipster : publicGameObject { • /* Game Logic ... */ inthealth; intspeed; intstrength; Behavior* behavior; }; classTrashCan : publicGameObject { inthitsBeforeBreaking; }; 1. Introduction
Production mode Game mode Tools programmer Engine programmer Everythingcan change Much more static Focus on productivity Focus on efficiency C# C++ But we all work together ! 1. Introduction
Need for Abstraction classHipster : publicGameObject { public: /* Game Logic ... */ private: inthealth; intspeed; Behavior* behavior; }; Edition intstrength; Serialization Versioning classHipster : publicGameObject { public: /* Game Logic ... */ private: inthealth; intspeed; intstrength; E_StrengthnewStrength; Behavior* behavior; }; • /* Auto-generated */ • virtualvoidSerialize(Serializer & serializer) • { • super::Serialize(serializer); • serializer >> health; • serializer >> speed; • serializer >> strength; • serializer >> behavior; • } 1. Introduction
Need for Reusability 1. Introduction
Need for Reusability 1. Introduction
WORLD 1 INTRODUCTION The Plan WORLD 3 SPECIALIZATION WORLD 2 REFLECTION WORLD 4 EDITOR EXPERIENCE
WORLD 1 INTRODUCTION The Plan WORLD 3 SPECIALIZATION WORLD 2 REFLECTION WORLD 4 EDITOR EXPERIENCE
Runtime Reflection (.Net Framework) • Has a runtime cost • Can get messy in C++ • Offline Reflection • Less intrusive • Can still generate engine code Reflection Archetypes 2. Reflection
Data Flow: Parsing Engine and Gameplay C++ Code Reflection Type Info Serialization Parsing Reflection Package 2. Reflection
Data Flow: Instances Reflection Type Info Serialization Game Data (Tool compatible) Instantiation Instances in Game Editor 2. Reflection
Data Flow: Launch EngineExecutable Binarization Launch Binary Data (Engine compatible) Instances in Game Editor 2. Reflection
Data Flow Game Data (Tool compatible) Parsing Engine and Gameplay C++ Code Reflection Type Info Serialization Compilation Instantiation Instances in Game Editor Binarization EngineExecutable Binary Data (Engine compatible) 2. Reflection
Syntax Parsing Engine and Gameplay C++ Code Reflection Type Info //<> Category("Actors") reflectedclassHipster : publicGameObject { private: • //<> Description("Health of the hipster") DefaultValue(40) reflectedinthealth; reflectedintspeed;//<> Category("Gameplay") DefaultValue(20) reflectedintstrength;//<> Category("Gameplay") DefaultValue(20) reflectedBehavior*behavior;//<> DefaultValue(IdleBehavior) reflection_statement ( • reflectedstringcomment; • ) }; 2. Reflection
WORLD 1 INTRODUCTION The Plan WORLD 3 DATA INHERITANCE WORLD 2 REFLECTION WORLD 4 EDITOR EXPERIENCE
WORLD 1 INTRODUCTION The Plan WORLD 3 DATA INHERITANCE WORLD 2 REFLECTION WORLD 4 EDITOR EXPERIENCE
HIPSTER TONY POS 0,0 HP 40 SPD 20 … A Typical Case POS 0,0 HP 40 SPD40 … BEN POS 0,0 HP 40 SPD15 … 3. Data Inheritance
POS 6,3 HP 40 SPD40 … A Typical Case POS 0,2 HP 40 SPD 20 … POS 4,1 HP 40 SPD15 … 3. Data Inheritance
POS 0,2 HP 40 SPD 20 … POS 6,3 HP 40 SPD40 … POS 0,2 HP 40 SPD 20 … POS 6,3 HP 40 SPD40 … POS 4,1 HP 40 SPD15 … A Typical Case POS 4,1 HP 40 SPD15 … POS 0,2 HP 40 SPD 20 … POS 6,3 HP 40 SPD40 … POS 4,1 HP 40 SPD15 … 3. Data Inheritance
STOP ? ? ? POS 0,2 HP 40 SPD 20 … POS 6,3 HP 40 SPD40 … ? POS 0,2 HP 40 SPD 20 … POS 6,3 HP 40 SPD40 … ? POS 4,1 HP 40 SPD15 … ? POS 4,1 HP 40 SPD15 … A Typical Case ? ? POS 0,2 HP 40 SPD 20 … POS 6,3 HP 40 SPD40 … ? POS 4,1 HP 40 SPD15 … 3. Data Inheritance
HP 50 … HP 50 … HP 50 … HP 50 … HP 50 … HP 50 … A Typical Case DATA INHERITANCE ! HP 50 … HP 50 … HP 50 … 3. Data Inheritance
Data Inheritance • Data reusability requires some relationship between different pieces of data. • Natural way of expressing edition problems. • Like styles in Word. • We embraced this paradigm completely. • Every piece of data can be specialized. 3. Data Inheritance
Similarity with Code • class Tony : public Hipster • { • virtual void Attack() • { … } • virtual void Block() • { /* New Behavior */ } • }; • classHipster • { • virtual void Attack() • { … } • virtual void Block() • { … } • }; • classThatHipster: public Tony • { • virtual void Attack() • { /* New Behavior */ } • virtual void Block() • { … } • }; • classThatHipster: public Hipster • { • virtual void Attack() • { /* New Behavior */ } • virtual void Block() • { … } • }; 3. Data Inheritance
Specializing Properties HP 40 SPD STR 20 20 40 25 HP SPD STR 30 40 25 HP 50 SPD30 STR 30 HP 50 SPD 40 STR 30 3. Data Inheritance
Specializing Behavior 3. Data Inheritance
Specializing Graphics 3. Data Inheritance
Specializing by Platform 3. Data Inheritance
Specializing Composition Physics Physics AI AI Physics 3. Data Inheritance AI
Specializing Composition 3. Data Inheritance
Deadly Diamond HP 40 GAME BOY TONY HP 30 HP 50 TONY ON GAME BOY? HP??? 3. Data Inheritance
Deadly Diamond (Solution) « TONY » CONTEXT WINS HP 50 (DEFINE CONTEXT PRIORITY) 3. Data Inheritance
HP 40 BASE HIPSTER * 3 TYPES * 200 INSTANCES PER LEVEL * 15 LEVELS* 5 PLATFORMS * 2 SKUS PER PLATFORM * ANY ARBITARY CRITERION=!!! HP 40 Scalability HP 40 HP 40 HP 40 3. Data Inheritance HP 40
- STRENGTH SAVE DELTAS ONLY!! POSSIBLE BECAUSE OF OFFLINE REPRESENTATION OF DATA Scalability + POSITION + BEHAVIOR 3. Data Inheritance
EACH VALUE IS IMPLEMENTED WITH A SORTED ARRAY HP Implementation BASE HIPSTER 30 PS3 40 TONY 50 TONY (SCENE 2) 55 TONY/PS3 45 3. Data Inheritance
QUERYING AN EXISTING VALUE (PS3) HP Implementation BASE HIPSTER 30 PS3 40 TONY 50 TONY (SCENE 2) 55 TONY/PS3 45 3. Data Inheritance
QUERYING AN INHERITED VALUE(STRONG, PS3, LEVEL2) HP Implementation BASE HIPSTER 30 PS3 40 TONY 50 TONY (SCENE 2) 55 TONY/PS3 45 3. Data Inheritance
WRITING A VALUE(TONY SCENE 2/PS3) HP Implementation BASE HIPSTER 30 PS3 40 TONY 50 TONY (SCENE 2) 55 TONY (SCENE 2)/PS3 45 TONY/PS3 45 3. Data Inheritance
RESETTING A VALUE(TONY SCENE 2) HP Implementation BASE HIPSTER 30 PS3 40 TONY 50 TONY (SCENE 2) 55 TONY/PS3 45 3. Data Inheritance
SPECIALIZATION LIST SCENE 2 A B C D A B E C D Implementation PS3 A B’ C D A B’ E C D 3. Data Inheritance
LEVEL A LEVEL A (PS3) 2 1 1 Interface LEVEL A, TONY 1 2 LEVEL A, TONY 2 HP SPD STR LEVEL A, TONY 2, PS3 3. Data Inheritance ALL HIPSTERS
EACH INSTANCE IS A PROXY IREFLECTED Interface HP IREFLECTED SPD STR 3. Data Inheritance ALL HIPSTERS
Usage IReflectedhipster = allHipsters.GetSpecialization(myContext); • hipster.SetValue(“strength”, 40); • intvalue = hipster.GetValue<int>(“strength”); 3. Data Inheritance
WORLD 1 INTRODUCTION The Plan WORLD 3 DATA INHERITANCE WORLD 2 REFLECTION WORLD 4 EDITOR EXPERIENCE
WORLD 1 INTRODUCTION The Plan WORLD 3 DATA INHERITANCE WORLD 2 REFLECTION WORLD 4 EDITOR EXPERIENCE
What Now? 4. Editor Experience
Editor Experience 4. Editor Experience
C# Type-safe Wrappers • IReflectedobj = ...; • // Double strength of hipster • intcurrentStrength = (int)obj.GetValue("strength"); • obj.SetValue("strength", currentStrength * 2); • IReflectedobj = ...; • // Cast in typesafe wrapper • Hipsterhipster = obj.Cast<Hipster>(); • // Double strength of hipster • hipster.Strength *= 2; 4. Editor Experience
C# Type-safe Wrappers • IReflectedobj = ...; • // Make sure behavior is angry • IReflectedbehavior = (IReflected)obj.GetValue("m_behavior"); • if (behavior == null || !behavior.Is("AngryBehavior")) • { • IReflectednewBehavior = • obj.ReflectionModule.Create("AngryBehavior"); • obj.SetValue("m_behavior", newBehavior); • } • IReflectedobj = ...; • // Cast in typesafe wrapper • Hipsterhipster = obj.Cast<Hipster>(); • // Make sure behavior is angry • if (!(hipster.BehaviorisAngryBehavior)) • { • hipster.Behavior = newAngryBehavior(); • } 4. Editor Experience
Accurate Previewing Editor 4. Editor Experience