SlideShare a Scribd company logo
geek & poke
A Dynamic Component Architecture
      for High Performance Gameplay


Terrance Cohen
Lead Systems Engineer
Insomniac Games
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose

• The Dynamic Component System

• Implementation by Example



• Questions (note slide #)
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose
  o Statement of Problem
  o Proposed Solution


• The Dynamic Component System

• Implementation by Example
Purpose : Statement of Problem

• Monolithic / deep Game Object hierarchy
  o Memory: binds data @ compile time
      Allocated throughout lifetime
Purpose : Statement of Problem

• Monolithic / deep Game Object hierarchy:
  o Memory: binds data @ compile time
  o Performance: poor cache coherence
      Arrays of non-homogeneous objects
      Virtual dispatch
      Fragmented instance data
Purpose : Statement of Problem

• Monolithic / deep Game Object hierarchy:
  o Memory: binds data @ compile time
  o Performance: poor cache coherence
  o Architecture: capability <=> inheritance
      Fixed at compile time
      Fully determined by class
      Change capabilities -> change hierarchy
Purpose : Statement of Problem

• Monolithic / deep Game Object hierarchy:
  o Memory: binds data @ compile time
  o Performance: poor cache coherence
  o Architecture: capability <=> inheritance


• "What we're used to"

• But select the best tool for the job.
Purpose : Statement of Problem

• Monolithic / deep Game Object hierarchy:
  o Memory: binds data @ compile time
  o Performance: poor cache coherence
  o Architecture: capability <=> inheritance


• "What we're used to"

• But select the best tool for the job.

• There's a better way!
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose
  o Statement of Problem
  o Proposed Solution


• The Dynamic Component System

• Implementation by Example
Purpose : Proposed Solution

• Construction of Game Object through composition of
  components at runtime
Purpose : Proposed Solution

• Construction of Game Object through composition of
  components at runtime

• Simple!

• Thank you for coming!
Purpose : Proposed Solution

• Construction of Game Object through composition of
  components at runtime

• Simple!

• Thank you for coming!

  o   Oh, you want details !?!
Purpose : Proposed Solution

• Construction of Game Object through composition of
  components at runtime

• Small chunks

• Represent a data transformation
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose

• The Dynamic Component System
  o Features


• Implementation by Example
The Dynamic Component System

• Evolution
   o Resistance 1 - Proof of Concept (1 type)
   o Resistance 2 - "Early Adopters" (32 types)
   o Ongoing (295 types as of May 1st 2010)
       Majority of new gameplay code
       Large portions of old gameplay refactored
The Dynamic Component System

• Evolution
   o Resistance 1 - Proof of Concept (1 type)
   o Resistance 2 - "Early Adopters" (32 types)
   o Ongoing (295 types as of May 1st 2010)
       Majority of new gameplay code
       Large portions of old gameplay refactored

• So it’s mature.
The Dynamic Component System

• Evolution
   o Resistance 1 - Proof of Concept (1 type)
   o Resistance 2 - "Early Adopters" (32 types)
   o Ongoing (295 types as of May 1st 2010)
       Majority of new gameplay code
       Large portions of old gameplay refactored

• So it’s mature. (No, not that way.)
The Dynamic Component System

• Side-by-side implementation
   o Not necessary to refactor existing code
   o Coexist with components


• General solution
The Dynamic Component System

• Does not address matters of
  o Reflection
  o Serialization
  o Data building
  o Instance versioning
  o ... those things are handled separately
      outside the scope of this discussion
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose

• The Dynamic Component System
  o Features


• Implementation by Example
Dynamic Component System : Features

• Components

• High-performance

• Dynamic

• System
Dynamic Component System : Features

• Components
   o Originally Aspects
   o Base Component class
       8 bytes of administrative data
   o Allocated from pools
       One pool per concrete type
       "Roster" indexes instances
       "Partition" separates allocated/free instances
Dynamic Component System : Features

• Components
• High-performance
   o Small, constant-time operations
       Allocate/free
       Resolve handle
       Get type
       Type implements (derived from)
   o No instance copying
Dynamic Component System : Features

• Components
• High-performance
   o Updates per-type (per-pool)
       Cache friendly
   o Encourage async update
       e.g. on SPU
          Roster: contiguous list of alloc'd instances
          Roster up to partition is DMA list
Dynamic Component System : Features

• Components
• High-performance
   o Resolving handle
       Small, constant-time operation:
          Index into Pool
          Compare generation
          Return Component*
Dynamic Component System : Features

• Components
• High-performance
• Dynamic
   o Runtime composition of game objects
       Dynamically alter behavior without baggage
   o Component allocated == in use
   o Pool sizes == max concurrent allocations
Dynamic Component System : Features

• Components
• High-performance
• Dynamic
   o High-frequency alloc() & free()
       alloc():
          test for availability
          make handle from index & generation
          increment Roster Partition
          Component::Init()
Dynamic Component System : Features

• Components
• High-performance
• Dynamic
   o High-frequency alloc() & free()
       alloc():
       free():
           Component::Deinit()
           swap Roster index with Partition-adjacent
            index
           decrement Partition
           increment generation
Demo : DynamicComponent::Free()
  //free the component from host's component chain                                                 
  void         DynamicComponent::Free( Type type, HostHandle host_handle, Chain& chain,     
                                       ComponentHandle& component_handle );                 
Demo : DynamicComponent::Free()
  //free the component from host's component chain                                                 
  void         DynamicComponent::Free( Type type, HostHandle host_handle, Chain& chain,     
                                       ComponentHandle& component_handle );                 
Demo : DynamicComponent::Free()
  //free the component from host's component chain                                                 
  void         DynamicComponent::Free( Type type, HostHandle host_handle, Chain& chain,     
                                       ComponentHandle& component_handle );                 
Demo : DynamicComponent::Free()
  //free the component from host's component chain                                                 
  void         DynamicComponent::Free( Type type, HostHandle host_handle, Chain& chain,     
                                       ComponentHandle& component_handle );                 
Demo : DynamicComponent::Free()
  //free the component from host's component chain                                                 
  void         DynamicComponent::Free( Type type, HostHandle host_handle, Chain& chain,     
                                       ComponentHandle& component_handle );                 
Dynamic Component System : Features

•   Components
•   High-performance
•   Dynamic
•   System
     o Not all-or-nothing!
     o Examples:
         Conversation
         Script Events
         Shots: no game object
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose

• The Dynamic Component System

• Implementation by Example
   o API
   o Script Events: Type Registration
   o Navigation: Allocation & Init
   o Shots: Asynchronous Update
namespace DynamicComponent
{
  //
  // Hosts' API
  //
  // Call these from GameObjects (or other objects) that host Dynamic Components
  //
___________________________________________________________________________________________________

  //allocate a component of type, add it to host's component chain,
  // and optionally park a prius in the component
  // returns null if no space is available for allocation
  Component*        Allocate                  ( Type type, HostHandle host_handle,
                                                Chain* chain, void* prius = NULL );
namespace DynamicComponent
{
  //
  // Hosts' API
  //
  // Call these from GameObjects (or other objects) that host Dynamic Components
  //

 Component*        Allocate                   ( Type type, HostHandle host_handle,
                                                Chain* chain, void* prius = NULL );
___________________________________________________________________________________________________

 //resolve a ComponentHandle to a Component
 // returns NULL if component_handle is null or is a stale handle
 // (i.e. component instance has been reused)
 Component*        ResolveHandle            ( Type type, ComponentHandle component_handle );
namespace DynamicComponent
{
  //
  // Hosts' API
  //
  // Call these from GameObjects (or other objects) that host Dynamic Components
  //

 Component*        Allocate                   ( Type type, HostHandle host_handle,
                                                Chain* chain, void* prius = NULL );
  Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
___________________________________________________________________________________________________

 //get one component of type that belongs to host
 Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
namespace DynamicComponent
{
  //
  // Hosts' API
  //
  // Call these from GameObjects (or other objects) that host Dynamic Components
  //

 Component*        Allocate                   ( Type type, HostHandle host_handle,
                                                Chain* chain, void* prius = NULL );
  Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
  Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
___________________________________________________________________________________________________

 //get the first Component in host's chain that implements the type interface
 Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
namespace DynamicComponent
{
  //
  // Hosts' API
  //
  // Call these from GameObjects (or other objects) that host Dynamic Components
  //

 Component*        Allocate                   ( Type type, HostHandle host_handle,
                                                Chain* chain, void* prius = NULL );
  Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
  Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
  Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
___________________________________________________________________________________________________

 //get all Components of type in host's chain, up to a max of count instances.
 // count should be passed with the size of the component array.
 // on return, count will contain the number of matching components, up to the specified limit.
 Component**       GetComponents             ( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
namespace DynamicComponent
{
  //
  // Hosts' API
  //
  // Call these from GameObjects (or other objects) that host Dynamic Components
  //

 Component*        Allocate                   ( Type type, HostHandle host_handle,
                                                Chain* chain, void* prius = NULL );
  Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
  Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
  Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
  Component**       GetComponents             ( Type type, HostHandle host_handle,
                                                Chain chain, u32& count );
___________________________________________________________________________________________________

 //get all Components in host's chain that implement type's interface.
 // count should be passed with the size of the component array.
 // on return, count will contain the number of matching components, up to the specified limit.
 Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
namespace DynamicComponent
{
  //
  // Hosts' API
  //
  // Call these from GameObjects (or other objects) that host Dynamic Components
  //

 Component*        Allocate                   ( Type type, HostHandle host_handle,
                                                Chain* chain, void* prius = NULL );
  Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
  Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
  Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
  Component**       GetComponents             ( Type type, HostHandle host_handle,
                                                Chain chain, u32& count );
  Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                                Chain chain, u32& count );
___________________________________________________________________________________________________

 //free the component from host's component chain
 void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                               ComponentHandle& component_handle );
namespace DynamicComponent
{
  //
  // Hosts' API
  //
  // Call these from GameObjects (or other objects) that host Dynamic Components
  //

 Component*        Allocate                   ( Type type, HostHandle host_handle,
                                                Chain* chain, void* prius = NULL );
  Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
  Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
  Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
  Component**       GetComponents             ( Type type, HostHandle host_handle,
                                                Chain chain, u32& count );
  Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                                Chain chain, u32& count );
  void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                                ComponentHandle& component_handle );
___________________________________________________________________________________________________

 //free all of the components in host's component chain
 // (GameObjects automatically free their component chain when they are destroyed)
 void              FreeChain                 ( HostHandle host_handle, Chain& chain );
namespace DynamicComponent
{
  //
  // Hosts' API
  //
  // Call these from GameObjects (or other objects) that host Dynamic Components
  //

 Component*        Allocate                   ( Type type, HostHandle host_handle,
                                                Chain* chain, void* prius = NULL );
  Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
  Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
  Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
  Component**       GetComponents             ( Type type, HostHandle host_handle,
                                                Chain chain, u32& count );
  Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                                Chain chain, u32& count );
  void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                                ComponentHandle& component_handle );
  void              FreeChain                 ( HostHandle host_handle, Chain& chain );
___________________________________________________________________________________________________

  //downcast a Component* to one of its subclasses.
  // please use this instead of the c-style '(Type*)object' so that casts are checked in debug
  //Example:
  // HeadComponent* my_head = COMPONENT_CAST(component_ptr, Head);
  //
#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );
namespace DynamicComponent
{
  // Hosts' API

 Component*        Allocate                  ( Type type, HostHandle host_handle,
                                               Chain* chain, void* prius = NULL );
 Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
 Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
 Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
 Component**       GetComponents             ( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                               ComponentHandle& component_handle );
 void              FreeChain                 ( HostHandle host_handle, Chain& chain );

#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );
___________________________________________________________________________________________________

 //
 // Systems' API
 //
 // Call these from systems that use the DCS
 //

 //get a list of component types that implement the interface of the given component type
 // count should be passed with the size of the types array.
 // on return, count will contain the number of matching component types,
 // up to the specified limit.
 Type*             GetTypesThatImplement     ( Type type, u32& count );
namespace DynamicComponent
{
  // Hosts' API

 Component*        Allocate                  ( Type type, HostHandle host_handle,
                                               Chain* chain, void* prius = NULL );
 Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
 Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
 Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
 Component**       GetComponents             ( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                               ComponentHandle& component_handle );
 void              FreeChain                 ( HostHandle host_handle, Chain& chain );

#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );

 //
 // Systems' API
 //
 // Call these from systems that use the DCS
 //

  Type*             GetTypesThatImplement     ( Type type, u32& count );
___________________________________________________________________________________________________

 //returns whether component type implements interface
 bool              TypeImplements            ( Type type, Type interface );
namespace DynamicComponent
{
  // Hosts' API

 Component*        Allocate                  ( Type type, HostHandle host_handle,
                                               Chain* chain, void* prius = NULL );
 Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
 Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
 Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
 Component**       GetComponents             ( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                               ComponentHandle& component_handle );
 void              FreeChain                 ( HostHandle host_handle, Chain& chain );

#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );

 //
 // Systems' API
 //
 // Call these from systems that use the DCS
 //

  Type*             GetTypesThatImplement     ( Type type, u32& count );
  bool              TypeImplements            ( Type type, Type interface );
___________________________________________________________________________________________________

 //returns the number of components of type that are currently allocated
 u32               GetNumAllocated           ( Type type );
namespace DynamicComponent
{
  // Hosts' API

 Component*        Allocate                  ( Type type, HostHandle host_handle,
                                               Chain* chain, void* prius = NULL );
 Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
 Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
 Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
 Component**       GetComponents             ( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                               ComponentHandle& component_handle );
 void              FreeChain                 ( HostHandle host_handle, Chain& chain );

#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );

 //
 // Systems' API
 //
 // Call these from systems that use the DCS
 //

  Type*             GetTypesThatImplement     ( Type type, u32& count );
  bool              TypeImplements            ( Type type, Type interface );
  u32               GetNumAllocated           ( Type type );
___________________________________________________________________________________________________

 //returns an array of pointers to all allocated components of type, their count,
 // and their size
 Component**       GetComponents             ( Type type, u32& count );
 //returns an array of all components of type (including unallocated instances!),
 // an array of the indices of allocated components within that array,
 // and the count of indices
 Component*        GetComponentsIndexed      ( Type type, u16*& indices, u32& count );
namespace DynamicComponent
{
  // Hosts' API

 Component*        Allocate                  ( Type type, HostHandle host_handle,
                                               Chain* chain, void* prius = NULL );
 Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
 Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
 Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
 Component**       GetComponents             ( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                               ComponentHandle& component_handle );
 void              FreeChain                 ( HostHandle host_handle, Chain& chain );

#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );

 //
 // Systems' API
 //
 // Call these from systems that use the DCS
 //

  Type*             GetTypesThatImplement     ( Type type, u32& count );
  bool              TypeImplements            ( Type type, Type interface );
  u32               GetNumAllocated           ( Type type );
  Component**       GetComponents             ( Type type, u32& count );
  Component*        GetComponentsIndexed      ( Type type, u16*& indices, u32& count );
___________________________________________________________________________________________________

 //updates all components of those types that want to be updated in the given UpdateStage
 void              UpdateComponents          ( UpdateStage::Enum stage );
namespace DynamicComponent
{
  // Hosts' API

 Component*        Allocate                  ( Type type, HostHandle host_handle,
                                               Chain* chain, void* prius = NULL );
 Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
 Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
 Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
 Component**       GetComponents             ( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                               ComponentHandle& component_handle );
 void              FreeChain                 ( HostHandle host_handle, Chain& chain );

#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );

 //
 // Systems' API
 //
 // Call these from systems that use the DCS
 //

  Type*             GetTypesThatImplement     ( Type type, u32& count );
  bool              TypeImplements            ( Type type, Type interface );
  u32               GetNumAllocated           ( Type type );
  Component**       GetComponents             ( Type type, u32& count );
  Component*        GetComponentsIndexed      ( Type type, u16*& indices, u32& count );
  void              UpdateComponents          ( UpdateStage::Enum stage );
___________________________________________________________________________________________________

 //frees a component that was allocated without a host, and is not in any chain
 void              Free                      ( Type type, ComponentHandle& component_handle );
namespace DynamicComponent
{
  // Hosts' API

 Component*        Allocate                  ( Type type, HostHandle host_handle,
                                               Chain* chain, void* prius = NULL );
 Component*        ResolveHandle             ( Type type, ComponentHandle component_handle );
 Component*        Get                       ( Type type, HostHandle host_handle, Chain chain );
 Component*        GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
 Component**       GetComponents             ( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 Component**       GetComponentsThatImplement( Type type, HostHandle host_handle,
                                               Chain chain, u32& count );
 void              Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                               ComponentHandle& component_handle );
 void              FreeChain                 ( HostHandle host_handle, Chain& chain );

#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );

 //
 // Systems' API
 //
 // Call these from systems that use the DCS
 //

  Type*             GetTypesThatImplement     ( Type type, u32& count );
  bool              TypeImplements            ( Type type, Type interface );
  u32               GetNumAllocated           ( Type type );
  Component**       GetComponents             ( Type type, u32& count );
  Component*        GetComponentsIndexed      ( Type type, u16*& indices, u32& count );
  void              UpdateComponents          ( UpdateStage::Enum stage );
  void              Free                      ( Type type, ComponentHandle& component_handle );
___________________________________________________________________________________________________

 //returns the current PPU UpdateStage::Enum.
 // will be UpdateStage::None unless UpdateComponents() is on the stack.
 UpdateStage::Enum GetCurrentUpdateStage      ( );
namespace DynamicComponent
{
  // Hosts' API

    Component*       Allocate                  ( Type type, HostHandle host_handle,
                                                 Chain* chain, void* prius = NULL );
    Component*       ResolveHandle             ( Type type, ComponentHandle component_handle );
    Component*       Get                       ( Type type, HostHandle host_handle, Chain chain );
    Component*       GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
    Component**      GetComponents             ( Type type, HostHandle host_handle,
                                                 Chain chain, u32& count );
    Component**      GetComponentsThatImplement( Type type, HostHandle host_handle,
                                                 Chain chain, u32& count );
    void             Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                                 ComponentHandle& component_handle );
    void             FreeChain                 ( HostHandle host_handle, Chain& chain );

#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );

    //
    // Systems' API
    //
    // Call these from systems that use the DCS
    //

  Type*             GetTypesThatImplement     ( Type type, u32& count );
  bool              TypeImplements            ( Type type, Type interface );
  u32               GetNumAllocated           ( Type type );
  Component**       GetComponents             ( Type type, u32& count );
  Component*        GetComponentsIndexed      ( Type type, u16*& indices, u32& count );
  void              UpdateComponents          ( UpdateStage::Enum stage );
  void              Free                      ( Type type, ComponentHandle& component_handle );
  UpdateStage::Enum GetCurrentUpdateStage     ( );
___________________________________________________________________________________________________

    //returns true iff type updates in stage
    u8                GetTypeUpdateStages         ( Type type );
}
namespace DynamicComponent
{
  // Hosts' API

    Component*          Allocate                  ( Type type, HostHandle host_handle,
                                                    Chain* chain, void* prius = NULL );
    Component*          ResolveHandle             ( Type type, ComponentHandle component_handle );
    Component*          Get                       ( Type type, HostHandle host_handle, Chain chain );
    Component*          GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
    Component**         GetComponents             ( Type type, HostHandle host_handle,
                                                    Chain chain, u32& count );
    Component**         GetComponentsThatImplement( Type type, HostHandle host_handle,
                                                    Chain chain, u32& count );
    void                Free                      ( Type type, HostHandle host_handle, Chain& chain,
                                                    ComponentHandle& component_handle );
    void                FreeChain                 ( HostHandle host_handle, Chain& chain );

#define COMPONENT_CAST(component, type) 
  ((type##Component*)ValidCast(component, DynamicComponent::type))
  inline Component* ValidCast                 ( Component* component, Type type );

    // Systems' API

    Type*               GetTypesThatImplement     (   Type type, u32& count );
    bool                TypeImplements            (   Type type, Type interface );
    u32                 GetNumAllocated           (   Type type );
    Component**         GetComponents             (   Type type, u32& count );
    Component*          GetComponentsIndexed      (   Type type, u16*& indices, u32& count );
    void                UpdateComponents          (   UpdateStage::Enum stage );
    void                Free                      (   Type type, ComponentHandle& component_handle );
    UpdateStage::Enum   GetCurrentUpdateStage     (   );
    u8                  GetTypeUpdateStages       (   Type type );
}
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose

• The Dynamic Component System

• Implementation by Example
   o API
   o Script Events: Type Registration
   o Navigation: Allocation & Init
   o Shots: Asynchronous Update
Script Events : Type Registration

• Script Events are Components
   o Hosted by the System
   o Possibly related to a Game Object


• Registered (allocated) from Lua
   o When conditions are met, call back


• Satisfaction:
   1.Updated: poll their conditions
   2.Notified by gameplay
Script Events : Type Registration

Notified             Updated

 •   Checkpoint       • Location
 •   Damage           • Timer
 •   Death            • Visible
 •   NumAlive
 •   Active
 •   Custom
      o Reload
      o Zoom
      o Grapple
      o SeatEnter
Script Events: Type Registration
  namespace DynamicComponent
  {
      typedef u16 Type;
      Type    unregistered_type       = 0xFFFF;
      Type    TypeRegistrar::RegisterType(
          const char*                 name,
          Type                        base_type           = unregistered_type,
          UpdateStage::Enum           update_stages       = UpdateStage::None,
          AsyncUpdateStage::Enum      async_update_stages = AsyncUpdateStage::None);
  }
Script Events: Type Registration
  namespace DynamicComponent
  {
      typedef u16 Type;
      Type    unregistered_type       = 0xFFFF;
      Type    TypeRegistrar::RegisterType(
          const char*                 name,
          Type                        base_type           = unregistered_type,
          UpdateStage::Enum           update_stages       = UpdateStage::None,
          AsyncUpdateStage::Enum      async_update_stages = AsyncUpdateStage::None);
  }




  using namespace DynamicComponent;

  void ScriptEventSystem::Init()
  {
  m_event_type        = TypeRegistrar::RegisterType("ScriptEvent");
  m_checkpoint_type   = TypeRegistrar::RegisterType("CheckpointEvent", m_event_type);
  m_location_type     = TypeRegistrar::RegisterType(
      "LocationEvent",
      m_event_type,                  //base class is ScriptEvent
      UpdateStage::PostUpdate,       //automatically updated on PPU during PostUpdate
      AsyncUpdateStage::PreUpdate);  //and on the SPU during the PreUpdate stage
  }
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose

• The Dynamic Component System

• Implementation by Example
   o API
   o Script Events: Type Registration
   o Navigation: Allocation & Init
   o Shots: Asynchronous Update
Navigation : Allocation & Initialization

• NavComponents are hosted by Game Objects

• Updated by the Navigation system
Navigation : Allocation & Initialization

• Remember the API call to allocate a component:
  //allocate a component of type, add it to host's component chain,
  //  and optionally park a prius in the component
  //  returns null if no space is available for allocation
  Component*        DynamicComponent::Allocate( Type type, HostHandle host_handle,
                                                Chain* chain, void*   prius = NULL );




• WTF is a prius?
Navigation : Allocation & Initialization

• Remember the API call to allocate a component:
   //allocate a component of type, add it to host's component chain,
   //  and optionally park a prius in the component
   //  returns null if no space is available for allocation
   Component*        DynamicComponent::Allocate( Type type, HostHandle host_handle,
                                                 Chain* chain, void*   prius = NULL );




 • WTF is a prius?
    o initialization data
    o Runtime or design-time data
 
 • void* But is that safe!?
Navigation : Allocation & Initialization
• Initialization
   o NavQuery is the Prius for a NavComponent
   o NavQuery::Submit() allocates a NavComponent, and
     passes itself as the prius.
NavComponent* NavQuery::Submit(GameObject* host)
{
  DynamicComponent::Type        type      = GetComponentType(); //virtual member of NavQuery
  DynamicComponent::Component*  component = host->AllocateComponent(type, this);
  NavComponent*                 nav       = COMPONENT_CAST(component, Nav);
  return nav;
}



• host->AllocateComponent()?  Helper in GameObject:
DynamicComponentComponent*
  GameObject::AllocateComponent(DynamicComponent::Type type, void* prius)
{
  return DynamicComponent::Allocate(type, m_handle, &m_component_chain, prius);
}
Navigation : Allocation & Initialization

• Gameplay code example
void FollowerBot::Initialize(GameObject* target)
{
  Nav::GameObjectQuery source_query  (this);    //query closest point to game object
  Nav::GameObjectQuery target_query  (target);
  Nav::PathQuery       path_query    (source_query, target_query);

  Nav::PathComponent*  m_path        = path_query.Submit();
}




• When navigation components are updated, endpoints
  and path are dynamically recomputed on SPU
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose

• The Dynamic Component System

• Implementation by Example
   o API
   o Script Events: Type Registration
   o Navigation: Allocation & Init
   o Shots: Asynchronous Update
Shots : Asynchronous Update

• Hosted by Game Object
• Replaces Projectile GameObjects

• Two DynamicComponent Type hierarchies:
   o Shot represents a state machine
       Notified
   o ShotAction represents the state of a Shot
       Updated
       Shared
Shots : Asynchronous Update
  #ifndef SPU //PPU only

  class ShotMoveForward : public ShotAction
  {
    DERIVED_COMPONENT(ShotMoveForward, ShotAction)

  public:

    virtual void    ParkPrius    (void* prius);
    virtual void    Update       (UpdateStage::Enum stage);

  #else        //SPU only

  struct ShotMoveForward
  {
    puspu_vec4      m_location    ALIGNED(16);    //shadows ShotAction::m_next_location on PPU

  #endif       //PPU & SPU shared

    puspu_vec4      m_direction;
    f32             m_speed;
  }                               __attribute__((aligned(16)));




• ShotAction::m_next_location on PPU and
  ShotMoveForward::m_location on SPU share the same address
Shots : Asynchronous Update

• How?  "Sentinel"
// async components must indicate where their async data begins
#define BEGIN_ASYNC_COMPONENT_DATA                        
    u32 m_async_data[0] __attribute__((aligned(16)));     




class ShotAction : public DynamicComponent::Component
{
  COMPONENT(ShotAction);

  // ...

  DynamicComponent::Handle    m_shot;
  DynamicComponent::Type      m_shot_type;

  BEGIN_ASYNC_COMPONENT_DATA

  vec4f                       m_next_location;
};
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose

• The Dynamic Component System

• Implementation by Example
A Dynamic Component Architecture
   for High Performance Gameplay


• Purpose

• The Dynamic Component System

• Implementation by Example

• Thank You!
• Questions
A Dynamic Component Architecture
    for High Performance Gameplay

• Visit me on the Web:
  http://www.TerranceCohen.com


• Follow me on Twitter:
  http://twitter.com/terrance_cohen


• Connect with me on LinkedIn:
  http://www.linkedin.com/in/terrancecohen


• Ask me anything:
  http://www.formspring.me/terrancecohen
A Dynamic Component Architecture
      for High Performance Gameplay

Terrance Cohen
Lead Systems Engineer
Insomniac Games
www.TerranceCohen.com
Twitter: @terrance_cohen

More Related Content

What's hot

CS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIsCS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
Kwangshin Oh
 
JDK1.6
JDK1.6JDK1.6
JDK1.6
india_mani
 
Automation Tool QTP
Automation Tool  QTPAutomation Tool  QTP
Automation Tool QTP
BugRaptors
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Martin Toshev
 
Introduction to Clojure
Introduction to ClojureIntroduction to Clojure
Introduction to Clojure
Renzo Borgatti
 
iOS Multithreading
iOS MultithreadingiOS Multithreading
iOS MultithreadingRicha Jain
 
Iterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design patternIterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design pattern
Nitin Bhide
 
Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel GeheugenDevnology
 
Java Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and Trends
Carol McDonald
 
UVM Driver sequencer handshaking
UVM Driver sequencer handshakingUVM Driver sequencer handshaking
UVM Driver sequencer handshaking
HARINATH REDDY
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in Practice
Alina Dolgikh
 
Core Java Programming Language (JSE) : Chapter X - I/O Fundamentals
Core Java Programming Language (JSE) : Chapter X - I/O Fundamentals Core Java Programming Language (JSE) : Chapter X - I/O Fundamentals
Core Java Programming Language (JSE) : Chapter X - I/O Fundamentals
WebStackAcademy
 
Java 8 Feature Preview
Java 8 Feature PreviewJava 8 Feature Preview
Java 8 Feature Preview
Jim Bethancourt
 
Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrency
feng lee
 
Java For Automation
Java   For AutomationJava   For Automation
Java For Automation
Abhijeet Dubey
 
Concurrency with java
Concurrency with javaConcurrency with java
Concurrency with java
Hoang Nguyen
 
Java Course 5: Enums, Generics, Assertions
Java Course 5: Enums, Generics, AssertionsJava Course 5: Enums, Generics, Assertions
Java Course 5: Enums, Generics, Assertions
Anton Keks
 

What's hot (19)

CS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIsCS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
 
JDK1.6
JDK1.6JDK1.6
JDK1.6
 
Automation Tool QTP
Automation Tool  QTPAutomation Tool  QTP
Automation Tool QTP
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Concurrency Utilities in Java 8
Concurrency Utilities in Java 8
 
Introduction to Clojure
Introduction to ClojureIntroduction to Clojure
Introduction to Clojure
 
iOS Multithreading
iOS MultithreadingiOS Multithreading
iOS Multithreading
 
Iterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design patternIterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design pattern
 
Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel Geheugen
 
Iterator
IteratorIterator
Iterator
 
Java Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and Trends
 
UVM Driver sequencer handshaking
UVM Driver sequencer handshakingUVM Driver sequencer handshaking
UVM Driver sequencer handshaking
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in Practice
 
Core Java Programming Language (JSE) : Chapter X - I/O Fundamentals
Core Java Programming Language (JSE) : Chapter X - I/O Fundamentals Core Java Programming Language (JSE) : Chapter X - I/O Fundamentals
Core Java Programming Language (JSE) : Chapter X - I/O Fundamentals
 
Java 7 New Features
Java 7 New FeaturesJava 7 New Features
Java 7 New Features
 
Java 8 Feature Preview
Java 8 Feature PreviewJava 8 Feature Preview
Java 8 Feature Preview
 
Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrency
 
Java For Automation
Java   For AutomationJava   For Automation
Java For Automation
 
Concurrency with java
Concurrency with javaConcurrency with java
Concurrency with java
 
Java Course 5: Enums, Generics, Assertions
Java Course 5: Enums, Generics, AssertionsJava Course 5: Enums, Generics, Assertions
Java Course 5: Enums, Generics, Assertions
 

Similar to GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay

GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay - M...
GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay - M...GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay - M...
GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay - M...
Terrance Cohen
 
0507 057 01 98 * Adana Cukurova Klima Servisleri
0507 057 01 98 * Adana Cukurova Klima Servisleri0507 057 01 98 * Adana Cukurova Klima Servisleri
Optimizing mobile applications - Ian Dundore, Mark Harkness
Optimizing mobile applications - Ian Dundore, Mark HarknessOptimizing mobile applications - Ian Dundore, Mark Harkness
Optimizing mobile applications - Ian Dundore, Mark Harkness
ozlael ozlael
 
Unity - Internals: memory and performance
Unity - Internals: memory and performanceUnity - Internals: memory and performance
Unity - Internals: memory and performance
Codemotion
 
Sephy engine development document
Sephy engine development documentSephy engine development document
Sephy engine development document
Jaejun Kim
 
Introduction to the Unreal Development Kit
Introduction to the Unreal Development KitIntroduction to the Unreal Development Kit
Introduction to the Unreal Development Kit
Nick Pruehs
 
Qtp - Introduction to synchronization
Qtp -  Introduction to synchronizationQtp -  Introduction to synchronization
Qtp - Introduction to synchronization
Vibrant Technologies & Computers
 
【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう
【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう
【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう
Unity Technologies Japan K.K.
 
React Development with the MERN Stack
React Development with the MERN StackReact Development with the MERN Stack
React Development with the MERN Stack
Troy Miles
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
Troy Miles
 
static MEMBER IN OOPS PROGRAMING LANGUAGE.pptx
static MEMBER IN OOPS PROGRAMING LANGUAGE.pptxstatic MEMBER IN OOPS PROGRAMING LANGUAGE.pptx
static MEMBER IN OOPS PROGRAMING LANGUAGE.pptx
urvashipundir04
 
static members in object oriented program.pptx
static members in object oriented program.pptxstatic members in object oriented program.pptx
static members in object oriented program.pptx
urvashipundir04
 
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle GamesWe Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
Unity Technologies
 
Ansiblefest 2018 Network automation journey at roblox
Ansiblefest 2018 Network automation journey at robloxAnsiblefest 2018 Network automation journey at roblox
Ansiblefest 2018 Network automation journey at roblox
Damien Garros
 
lecture-18staticdatamember-160705095116.pdf
lecture-18staticdatamember-160705095116.pdflecture-18staticdatamember-160705095116.pdf
lecture-18staticdatamember-160705095116.pdf
AneesAbbasi14
 
Angular Weekend
Angular WeekendAngular Weekend
Angular Weekend
Troy Miles
 
98 374 Lesson 06-slides
98 374 Lesson 06-slides98 374 Lesson 06-slides
98 374 Lesson 06-slides
Tracie King
 
[OOP - Lec 18] Static Data Member
[OOP - Lec 18] Static Data Member[OOP - Lec 18] Static Data Member
[OOP - Lec 18] Static Data Member
Muhammad Hammad Waseem
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disqus
zeeg
 

Similar to GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay (20)

GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay - M...
GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay - M...GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay - M...
GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay - M...
 
0507 057 01 98 * Adana Cukurova Klima Servisleri
0507 057 01 98 * Adana Cukurova Klima Servisleri0507 057 01 98 * Adana Cukurova Klima Servisleri
0507 057 01 98 * Adana Cukurova Klima Servisleri
 
Optimizing mobile applications - Ian Dundore, Mark Harkness
Optimizing mobile applications - Ian Dundore, Mark HarknessOptimizing mobile applications - Ian Dundore, Mark Harkness
Optimizing mobile applications - Ian Dundore, Mark Harkness
 
Unity - Internals: memory and performance
Unity - Internals: memory and performanceUnity - Internals: memory and performance
Unity - Internals: memory and performance
 
Sephy engine development document
Sephy engine development documentSephy engine development document
Sephy engine development document
 
Introduction to the Unreal Development Kit
Introduction to the Unreal Development KitIntroduction to the Unreal Development Kit
Introduction to the Unreal Development Kit
 
Qtp - Introduction to synchronization
Qtp -  Introduction to synchronizationQtp -  Introduction to synchronization
Qtp - Introduction to synchronization
 
【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう
【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう
【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう
 
React Development with the MERN Stack
React Development with the MERN StackReact Development with the MERN Stack
React Development with the MERN Stack
 
Soc research
Soc researchSoc research
Soc research
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
static MEMBER IN OOPS PROGRAMING LANGUAGE.pptx
static MEMBER IN OOPS PROGRAMING LANGUAGE.pptxstatic MEMBER IN OOPS PROGRAMING LANGUAGE.pptx
static MEMBER IN OOPS PROGRAMING LANGUAGE.pptx
 
static members in object oriented program.pptx
static members in object oriented program.pptxstatic members in object oriented program.pptx
static members in object oriented program.pptx
 
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle GamesWe Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
 
Ansiblefest 2018 Network automation journey at roblox
Ansiblefest 2018 Network automation journey at robloxAnsiblefest 2018 Network automation journey at roblox
Ansiblefest 2018 Network automation journey at roblox
 
lecture-18staticdatamember-160705095116.pdf
lecture-18staticdatamember-160705095116.pdflecture-18staticdatamember-160705095116.pdf
lecture-18staticdatamember-160705095116.pdf
 
Angular Weekend
Angular WeekendAngular Weekend
Angular Weekend
 
98 374 Lesson 06-slides
98 374 Lesson 06-slides98 374 Lesson 06-slides
98 374 Lesson 06-slides
 
[OOP - Lec 18] Static Data Member
[OOP - Lec 18] Static Data Member[OOP - Lec 18] Static Data Member
[OOP - Lec 18] Static Data Member
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disqus
 

Recently uploaded

UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 

Recently uploaded (20)

UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 

GDC 2010 - A Dynamic Component Architecture for High Performance Gameplay

  • 1.
  • 2.
  • 3.
  • 5. A Dynamic Component Architecture for High Performance Gameplay Terrance Cohen Lead Systems Engineer Insomniac Games
  • 6. A Dynamic Component Architecture for High Performance Gameplay • Purpose • The Dynamic Component System • Implementation by Example • Questions (note slide #)
  • 7. A Dynamic Component Architecture for High Performance Gameplay • Purpose o Statement of Problem o Proposed Solution • The Dynamic Component System • Implementation by Example
  • 8. Purpose : Statement of Problem • Monolithic / deep Game Object hierarchy o Memory: binds data @ compile time  Allocated throughout lifetime
  • 9. Purpose : Statement of Problem • Monolithic / deep Game Object hierarchy: o Memory: binds data @ compile time o Performance: poor cache coherence  Arrays of non-homogeneous objects  Virtual dispatch  Fragmented instance data
  • 10. Purpose : Statement of Problem • Monolithic / deep Game Object hierarchy: o Memory: binds data @ compile time o Performance: poor cache coherence o Architecture: capability <=> inheritance  Fixed at compile time  Fully determined by class  Change capabilities -> change hierarchy
  • 11. Purpose : Statement of Problem • Monolithic / deep Game Object hierarchy: o Memory: binds data @ compile time o Performance: poor cache coherence o Architecture: capability <=> inheritance • "What we're used to" • But select the best tool for the job.
  • 12. Purpose : Statement of Problem • Monolithic / deep Game Object hierarchy: o Memory: binds data @ compile time o Performance: poor cache coherence o Architecture: capability <=> inheritance • "What we're used to" • But select the best tool for the job. • There's a better way!
  • 13. A Dynamic Component Architecture for High Performance Gameplay • Purpose o Statement of Problem o Proposed Solution • The Dynamic Component System • Implementation by Example
  • 14. Purpose : Proposed Solution • Construction of Game Object through composition of components at runtime
  • 15. Purpose : Proposed Solution • Construction of Game Object through composition of components at runtime • Simple! • Thank you for coming!
  • 16. Purpose : Proposed Solution • Construction of Game Object through composition of components at runtime • Simple! • Thank you for coming! o Oh, you want details !?!
  • 17. Purpose : Proposed Solution • Construction of Game Object through composition of components at runtime • Small chunks • Represent a data transformation
  • 18. A Dynamic Component Architecture for High Performance Gameplay • Purpose • The Dynamic Component System o Features • Implementation by Example
  • 19. The Dynamic Component System • Evolution o Resistance 1 - Proof of Concept (1 type) o Resistance 2 - "Early Adopters" (32 types) o Ongoing (295 types as of May 1st 2010)  Majority of new gameplay code  Large portions of old gameplay refactored
  • 20. The Dynamic Component System • Evolution o Resistance 1 - Proof of Concept (1 type) o Resistance 2 - "Early Adopters" (32 types) o Ongoing (295 types as of May 1st 2010)  Majority of new gameplay code  Large portions of old gameplay refactored • So it’s mature.
  • 21. The Dynamic Component System • Evolution o Resistance 1 - Proof of Concept (1 type) o Resistance 2 - "Early Adopters" (32 types) o Ongoing (295 types as of May 1st 2010)  Majority of new gameplay code  Large portions of old gameplay refactored • So it’s mature. (No, not that way.)
  • 22. The Dynamic Component System • Side-by-side implementation o Not necessary to refactor existing code o Coexist with components • General solution
  • 23. The Dynamic Component System • Does not address matters of o Reflection o Serialization o Data building o Instance versioning o ... those things are handled separately  outside the scope of this discussion
  • 24. A Dynamic Component Architecture for High Performance Gameplay • Purpose • The Dynamic Component System o Features • Implementation by Example
  • 25. Dynamic Component System : Features • Components • High-performance • Dynamic • System
  • 26. Dynamic Component System : Features • Components o Originally Aspects o Base Component class  8 bytes of administrative data o Allocated from pools  One pool per concrete type  "Roster" indexes instances  "Partition" separates allocated/free instances
  • 27. Dynamic Component System : Features • Components • High-performance o Small, constant-time operations  Allocate/free  Resolve handle  Get type  Type implements (derived from) o No instance copying
  • 28. Dynamic Component System : Features • Components • High-performance o Updates per-type (per-pool)  Cache friendly o Encourage async update  e.g. on SPU  Roster: contiguous list of alloc'd instances  Roster up to partition is DMA list
  • 29. Dynamic Component System : Features • Components • High-performance o Resolving handle  Small, constant-time operation:  Index into Pool  Compare generation  Return Component*
  • 30. Dynamic Component System : Features • Components • High-performance • Dynamic o Runtime composition of game objects  Dynamically alter behavior without baggage o Component allocated == in use o Pool sizes == max concurrent allocations
  • 31. Dynamic Component System : Features • Components • High-performance • Dynamic o High-frequency alloc() & free()  alloc():  test for availability  make handle from index & generation  increment Roster Partition  Component::Init()
  • 32. Dynamic Component System : Features • Components • High-performance • Dynamic o High-frequency alloc() & free()  alloc():  free():  Component::Deinit()  swap Roster index with Partition-adjacent index  decrement Partition  increment generation
  • 38. Dynamic Component System : Features • Components • High-performance • Dynamic • System o Not all-or-nothing! o Examples:  Conversation  Script Events  Shots: no game object
  • 39. A Dynamic Component Architecture for High Performance Gameplay • Purpose • The Dynamic Component System • Implementation by Example o API o Script Events: Type Registration o Navigation: Allocation & Init o Shots: Asynchronous Update
  • 40. namespace DynamicComponent { // // Hosts' API // // Call these from GameObjects (or other objects) that host Dynamic Components // ___________________________________________________________________________________________________ //allocate a component of type, add it to host's component chain, // and optionally park a prius in the component // returns null if no space is available for allocation Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL );
  • 41. namespace DynamicComponent { // // Hosts' API // // Call these from GameObjects (or other objects) that host Dynamic Components // Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); ___________________________________________________________________________________________________ //resolve a ComponentHandle to a Component // returns NULL if component_handle is null or is a stale handle // (i.e. component instance has been reused) Component* ResolveHandle ( Type type, ComponentHandle component_handle );
  • 42. namespace DynamicComponent { // // Hosts' API // // Call these from GameObjects (or other objects) that host Dynamic Components // Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); ___________________________________________________________________________________________________ //get one component of type that belongs to host Component* Get ( Type type, HostHandle host_handle, Chain chain );
  • 43. namespace DynamicComponent { // // Hosts' API // // Call these from GameObjects (or other objects) that host Dynamic Components // Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); ___________________________________________________________________________________________________ //get the first Component in host's chain that implements the type interface Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
  • 44. namespace DynamicComponent { // // Hosts' API // // Call these from GameObjects (or other objects) that host Dynamic Components // Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); ___________________________________________________________________________________________________ //get all Components of type in host's chain, up to a max of count instances. // count should be passed with the size of the component array. // on return, count will contain the number of matching components, up to the specified limit. Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count );
  • 45. namespace DynamicComponent { // // Hosts' API // // Call these from GameObjects (or other objects) that host Dynamic Components // Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); ___________________________________________________________________________________________________ //get all Components in host's chain that implement type's interface. // count should be passed with the size of the component array. // on return, count will contain the number of matching components, up to the specified limit. Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count );
  • 46. namespace DynamicComponent { // // Hosts' API // // Call these from GameObjects (or other objects) that host Dynamic Components // Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); ___________________________________________________________________________________________________ //free the component from host's component chain void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle );
  • 47. namespace DynamicComponent { // // Hosts' API // // Call these from GameObjects (or other objects) that host Dynamic Components // Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); ___________________________________________________________________________________________________ //free all of the components in host's component chain // (GameObjects automatically free their component chain when they are destroyed) void FreeChain ( HostHandle host_handle, Chain& chain );
  • 48. namespace DynamicComponent { // // Hosts' API // // Call these from GameObjects (or other objects) that host Dynamic Components // Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); ___________________________________________________________________________________________________ //downcast a Component* to one of its subclasses. // please use this instead of the c-style '(Type*)object' so that casts are checked in debug //Example: // HeadComponent* my_head = COMPONENT_CAST(component_ptr, Head); // #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type );
  • 49. namespace DynamicComponent { // Hosts' API Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type ); ___________________________________________________________________________________________________ // // Systems' API // // Call these from systems that use the DCS // //get a list of component types that implement the interface of the given component type // count should be passed with the size of the types array. // on return, count will contain the number of matching component types, // up to the specified limit. Type* GetTypesThatImplement ( Type type, u32& count );
  • 50. namespace DynamicComponent { // Hosts' API Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type ); // // Systems' API // // Call these from systems that use the DCS // Type* GetTypesThatImplement ( Type type, u32& count ); ___________________________________________________________________________________________________ //returns whether component type implements interface bool TypeImplements ( Type type, Type interface );
  • 51. namespace DynamicComponent { // Hosts' API Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type ); // // Systems' API // // Call these from systems that use the DCS // Type* GetTypesThatImplement ( Type type, u32& count ); bool TypeImplements ( Type type, Type interface ); ___________________________________________________________________________________________________ //returns the number of components of type that are currently allocated u32 GetNumAllocated ( Type type );
  • 52. namespace DynamicComponent { // Hosts' API Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type ); // // Systems' API // // Call these from systems that use the DCS // Type* GetTypesThatImplement ( Type type, u32& count ); bool TypeImplements ( Type type, Type interface ); u32 GetNumAllocated ( Type type ); ___________________________________________________________________________________________________ //returns an array of pointers to all allocated components of type, their count, // and their size Component** GetComponents ( Type type, u32& count ); //returns an array of all components of type (including unallocated instances!), // an array of the indices of allocated components within that array, // and the count of indices Component* GetComponentsIndexed ( Type type, u16*& indices, u32& count );
  • 53. namespace DynamicComponent { // Hosts' API Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type ); // // Systems' API // // Call these from systems that use the DCS // Type* GetTypesThatImplement ( Type type, u32& count ); bool TypeImplements ( Type type, Type interface ); u32 GetNumAllocated ( Type type ); Component** GetComponents ( Type type, u32& count ); Component* GetComponentsIndexed ( Type type, u16*& indices, u32& count ); ___________________________________________________________________________________________________ //updates all components of those types that want to be updated in the given UpdateStage void UpdateComponents ( UpdateStage::Enum stage );
  • 54. namespace DynamicComponent { // Hosts' API Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type ); // // Systems' API // // Call these from systems that use the DCS // Type* GetTypesThatImplement ( Type type, u32& count ); bool TypeImplements ( Type type, Type interface ); u32 GetNumAllocated ( Type type ); Component** GetComponents ( Type type, u32& count ); Component* GetComponentsIndexed ( Type type, u16*& indices, u32& count ); void UpdateComponents ( UpdateStage::Enum stage ); ___________________________________________________________________________________________________ //frees a component that was allocated without a host, and is not in any chain void Free ( Type type, ComponentHandle& component_handle );
  • 55. namespace DynamicComponent { // Hosts' API Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type ); // // Systems' API // // Call these from systems that use the DCS // Type* GetTypesThatImplement ( Type type, u32& count ); bool TypeImplements ( Type type, Type interface ); u32 GetNumAllocated ( Type type ); Component** GetComponents ( Type type, u32& count ); Component* GetComponentsIndexed ( Type type, u16*& indices, u32& count ); void UpdateComponents ( UpdateStage::Enum stage ); void Free ( Type type, ComponentHandle& component_handle ); ___________________________________________________________________________________________________ //returns the current PPU UpdateStage::Enum. // will be UpdateStage::None unless UpdateComponents() is on the stack. UpdateStage::Enum GetCurrentUpdateStage ( );
  • 56. namespace DynamicComponent { // Hosts' API Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type ); // // Systems' API // // Call these from systems that use the DCS // Type* GetTypesThatImplement ( Type type, u32& count ); bool TypeImplements ( Type type, Type interface ); u32 GetNumAllocated ( Type type ); Component** GetComponents ( Type type, u32& count ); Component* GetComponentsIndexed ( Type type, u16*& indices, u32& count ); void UpdateComponents ( UpdateStage::Enum stage ); void Free ( Type type, ComponentHandle& component_handle ); UpdateStage::Enum GetCurrentUpdateStage ( ); ___________________________________________________________________________________________________ //returns true iff type updates in stage u8 GetTypeUpdateStages ( Type type ); }
  • 57. namespace DynamicComponent { // Hosts' API Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL ); Component* ResolveHandle ( Type type, ComponentHandle component_handle ); Component* Get ( Type type, HostHandle host_handle, Chain chain ); Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain ); Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count ); Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count ); void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle ); void FreeChain ( HostHandle host_handle, Chain& chain ); #define COMPONENT_CAST(component, type) ((type##Component*)ValidCast(component, DynamicComponent::type)) inline Component* ValidCast ( Component* component, Type type ); // Systems' API Type* GetTypesThatImplement ( Type type, u32& count ); bool TypeImplements ( Type type, Type interface ); u32 GetNumAllocated ( Type type ); Component** GetComponents ( Type type, u32& count ); Component* GetComponentsIndexed ( Type type, u16*& indices, u32& count ); void UpdateComponents ( UpdateStage::Enum stage ); void Free ( Type type, ComponentHandle& component_handle ); UpdateStage::Enum GetCurrentUpdateStage ( ); u8 GetTypeUpdateStages ( Type type ); }
  • 58. A Dynamic Component Architecture for High Performance Gameplay • Purpose • The Dynamic Component System • Implementation by Example o API o Script Events: Type Registration o Navigation: Allocation & Init o Shots: Asynchronous Update
  • 59. Script Events : Type Registration • Script Events are Components o Hosted by the System o Possibly related to a Game Object • Registered (allocated) from Lua o When conditions are met, call back • Satisfaction: 1.Updated: poll their conditions 2.Notified by gameplay
  • 60. Script Events : Type Registration Notified Updated • Checkpoint • Location • Damage • Timer • Death • Visible • NumAlive • Active • Custom o Reload o Zoom o Grapple o SeatEnter
  • 61. Script Events: Type Registration   namespace DynamicComponent   {       typedef u16 Type;       Type    unregistered_type       = 0xFFFF;       Type    TypeRegistrar::RegisterType(           const char*                 name,           Type                        base_type           = unregistered_type,           UpdateStage::Enum           update_stages       = UpdateStage::None,           AsyncUpdateStage::Enum      async_update_stages = AsyncUpdateStage::None);   }
  • 62. Script Events: Type Registration   namespace DynamicComponent   {       typedef u16 Type;       Type    unregistered_type       = 0xFFFF;       Type    TypeRegistrar::RegisterType(           const char*                 name,           Type                        base_type           = unregistered_type,           UpdateStage::Enum           update_stages       = UpdateStage::None,           AsyncUpdateStage::Enum      async_update_stages = AsyncUpdateStage::None);   }   using namespace DynamicComponent;   void ScriptEventSystem::Init()   {   m_event_type        = TypeRegistrar::RegisterType("ScriptEvent");   m_checkpoint_type   = TypeRegistrar::RegisterType("CheckpointEvent", m_event_type);   m_location_type     = TypeRegistrar::RegisterType(       "LocationEvent",       m_event_type,                  //base class is ScriptEvent       UpdateStage::PostUpdate,       //automatically updated on PPU during PostUpdate       AsyncUpdateStage::PreUpdate);  //and on the SPU during the PreUpdate stage   }
  • 63. A Dynamic Component Architecture for High Performance Gameplay • Purpose • The Dynamic Component System • Implementation by Example o API o Script Events: Type Registration o Navigation: Allocation & Init o Shots: Asynchronous Update
  • 64. Navigation : Allocation & Initialization • NavComponents are hosted by Game Objects • Updated by the Navigation system
  • 65. Navigation : Allocation & Initialization • Remember the API call to allocate a component:   //allocate a component of type, add it to host's component chain,   //  and optionally park a prius in the component   //  returns null if no space is available for allocation   Component*        DynamicComponent::Allocate( Type type, HostHandle host_handle,                                                 Chain* chain, void* prius = NULL ); • WTF is a prius?
  • 66. Navigation : Allocation & Initialization • Remember the API call to allocate a component:   //allocate a component of type, add it to host's component chain,   //  and optionally park a prius in the component   //  returns null if no space is available for allocation   Component*        DynamicComponent::Allocate( Type type, HostHandle host_handle,                                                 Chain* chain, void* prius = NULL ); • WTF is a prius? o initialization data o Runtime or design-time data   • void* But is that safe!?
  • 67. Navigation : Allocation & Initialization • Initialization o NavQuery is the Prius for a NavComponent o NavQuery::Submit() allocates a NavComponent, and passes itself as the prius. NavComponent* NavQuery::Submit(GameObject* host) {   DynamicComponent::Type        type      = GetComponentType(); //virtual member of NavQuery   DynamicComponent::Component*  component = host->AllocateComponent(type, this);   NavComponent*                 nav       = COMPONENT_CAST(component, Nav);   return nav; } • host->AllocateComponent()?  Helper in GameObject: DynamicComponentComponent*   GameObject::AllocateComponent(DynamicComponent::Type type, void* prius) {   return DynamicComponent::Allocate(type, m_handle, &m_component_chain, prius); }
  • 68. Navigation : Allocation & Initialization • Gameplay code example void FollowerBot::Initialize(GameObject* target) {   Nav::GameObjectQuery source_query  (this);    //query closest point to game object   Nav::GameObjectQuery target_query  (target);   Nav::PathQuery       path_query    (source_query, target_query);   Nav::PathComponent*  m_path        = path_query.Submit(); } • When navigation components are updated, endpoints and path are dynamically recomputed on SPU
  • 69. A Dynamic Component Architecture for High Performance Gameplay • Purpose • The Dynamic Component System • Implementation by Example o API o Script Events: Type Registration o Navigation: Allocation & Init o Shots: Asynchronous Update
  • 70. Shots : Asynchronous Update • Hosted by Game Object • Replaces Projectile GameObjects • Two DynamicComponent Type hierarchies: o Shot represents a state machine  Notified o ShotAction represents the state of a Shot  Updated  Shared
  • 71. Shots : Asynchronous Update   #ifndef SPU //PPU only   class ShotMoveForward : public ShotAction   {     DERIVED_COMPONENT(ShotMoveForward, ShotAction)   public:     virtual void    ParkPrius    (void* prius);     virtual void    Update       (UpdateStage::Enum stage);   #else        //SPU only   struct ShotMoveForward   {     puspu_vec4      m_location    ALIGNED(16);    //shadows ShotAction::m_next_location on PPU   #endif       //PPU & SPU shared     puspu_vec4      m_direction;     f32             m_speed;   }                               __attribute__((aligned(16))); • ShotAction::m_next_location on PPU and ShotMoveForward::m_location on SPU share the same address
  • 72. Shots : Asynchronous Update • How?  "Sentinel" // async components must indicate where their async data begins #define BEGIN_ASYNC_COMPONENT_DATA                             u32 m_async_data[0] __attribute__((aligned(16)));      class ShotAction : public DynamicComponent::Component {   COMPONENT(ShotAction);   // ...   DynamicComponent::Handle    m_shot;   DynamicComponent::Type      m_shot_type;   BEGIN_ASYNC_COMPONENT_DATA   vec4f                       m_next_location; };
  • 73. A Dynamic Component Architecture for High Performance Gameplay • Purpose • The Dynamic Component System • Implementation by Example
  • 74. A Dynamic Component Architecture for High Performance Gameplay • Purpose • The Dynamic Component System • Implementation by Example • Thank You! • Questions
  • 75. A Dynamic Component Architecture for High Performance Gameplay • Visit me on the Web: http://www.TerranceCohen.com • Follow me on Twitter: http://twitter.com/terrance_cohen • Connect with me on LinkedIn: http://www.linkedin.com/in/terrancecohen • Ask me anything: http://www.formspring.me/terrancecohen
  • 76. A Dynamic Component Architecture for High Performance Gameplay Terrance Cohen Lead Systems Engineer Insomniac Games www.TerranceCohen.com Twitter: @terrance_cohen

Editor's Notes

  1. Waiting for people to arrive
  2. Waiting for people to arrive
  3. Waiting for people to arrive
  4. Waiting for people to arrive
  5. Follow me on Twitter: http://twitter.com/terrance_cohen Connect with me on LinkedIn: http://www.linkedin.com/in/terrancecohen Ask me a question: http://www.formspring.me/terrancecohen
  6. At a high level, I have three sections to this discussion First, we&apos;ll talk about, &quot;Why are we here?&quot; Not, &quot;Why are we here on this earth,&quot; that&apos;s outside the scope of this presentation.  I mean, &quot;What do I hope you&apos;ll conclude from this.&quot; We&apos;ll discuss the problem we&apos;re trying to solve, and my approach to a solution Second, we&apos;ll talk about details of my solution, which I call the Dynamic Component System. We&apos;ll discuss features of the system, and why it&apos;s a good solution And third, we&apos;ll dig into implementation details of the system, Using a few systems of dynamic components for illustration purposes
  7. First we&apos;ll talk about the problem we&apos;re trying to solve.
  8. This is the traditional OO game object based gameplay model Member data allocated throughout lifetime, even when not in use Some designs will allocate some data separately from the game object, e.g. a physics instance But this is counter to the architecture, rather than central to the architecture, And each system is likely to roll it’s own solution, since the unifying architecture doesn’t support it
  9. Encourages iteration over arrays of non-homogeneous objects Encourages virtual dispatch in the most unpredictable patterns Instance data fragmented by unused elements These are general issues with performance under OO
  10. Capabilities of an object are fixed at compile time, fully determined by class Changing capabilities means changing hierarchy often impossible without code duplication or multiple inheritance of implementation both have serious drawbacks Changing capabilities through multiple inheritance: Some will argue that there are no serious drawbacks to MI Beyond the scope of this discussion Even for strong proponents of such architecture, should agree that it&apos;s not a good solution to this  problem Messy unification of disparate hierarchies
  11. &quot;What we&apos;re used to,&quot; so easy to overlook flaws Step back.  Select the best tool for the job.
  12. So here&apos;s my attempt at a solution.  It&apos;s worked well for us.  I hope it&apos;ll work well for you.
  13. Everything that the Game Object represents can be broken-down into small chunks Each component represents a data transformation Ultimately, that&apos;s all the game is doing e.g. state machine + states e.g. model animation physics ai/logic sensing send/receive messaging causing damage
  14. So now we&apos;ll talk about my solution which I call the Dynamic Component System. First we&apos;ll talk at a high level about what is the system
  15. Not in the “adults only” sense. It’s been exercised.
  16. Side-by-side implementation Not necessary to refactor existing code Game objects in the traditional (or &quot;legacy&quot;) monolithic model can coexist and interoperate with components The solution is general - doesn&apos;t require a particular game architecture. Some environment-specific implementation details
  17. sorry if you were looking for tips on those things if you&apos;re interested in my thoughts on those subjects, please contact me afterward
  18. Now we&apos;ll discuss features of the system, a.k.a. why I think it&apos;s a good solution.
  19. Components Originally called Aspects from AOP Derived from base Component class 12 bytes of administrative data &quot;Payload&quot; can be detached &amp; treated as POD for processing in separate memory spaces Allocated from pools One pool per concrete type Homogeneous type instances per pool Each pool is indexed with a &quot;partition&quot; value separating free from allocated instances Called the &quot;Roster&quot;
  20. High-performance All operations, except for &quot;search&quot;, are small constant-time Allocate/free Resolve handle Get type Type implements (derived from) No instance copying manipulations are done on the Roster rather than the instance pool
  21. High-performance Updates are performed per-type (per-pool) Cache friendly Designed to encourage &amp; simplify async update e.g. on SPU Roster contains contiguous list of pool indices of allocated instances Roster up to partition is DMA list
  22. High-performance: References between components normally handled by holding/resolving handles
  23. Dynamic: Runtime composition of game objects Objects can substantially alter any aspect without carrying around any &quot;baggage&quot; from other states Recommended idiom: component is allocated IFF actively in use Pool sizes need only accommodate max concurrent allocations
  24. Dynamic: Results: High-frequency alloc() &amp; free() Small constant-time operations: alloc(): test for availability make handle from index &amp; generation increment roster partition call Init on allocated component
  25. Dynamic Results: High-frequency alloc() &amp; free() Small constant-time operations: free(): call Deinit swap index in roster with partition-adjacent index decrement partition increment generation So let&apos;s take an example to put some of these pieces together. We&apos;ll look at an example of freeing a dynamic component instance.
  26. Here&apos;s the prototype for DynamicComponent::Free().  It takes... So here&apos;s an example. We have a pool of instances of some given component type. We have a roster, which is an array of indices into the instance pool.  (Note that all of the instances in the pool are of the same type, so they are of equal size.  So the value at a roster index is itself just an index into the pool. You can see that we have a partition value, which separates roster indices representing allocated vs. free instances.
  27. Alright.  Now we&apos;re going to free the component represented by the 3rd roster element, which is currently index 3 in the pool.
  28. So what we&apos;ll do is swap the 3rd and 4th roster elements.
  29. Now we&apos;re freeing the 4th roster element, which represents the 3rd instance in the pool. Since we swapped the roster entry for the element to be freed into the partition-adjacent roster entry, all we have to do to free that instance is...
  30. ... decrement the partition. And voila, we&apos;ve free&apos;d a component instance with a few very small constant-time operations, and we didn&apos;t touch the instance data, only indices.
  31. System Doesn&apos;t need to completely replace a standard game object model Can completely replace standard game object model Other systems host components Conversation Script Events Shots No game object
  32. At a high level, I have three sections to this discussion So now we&apos;re digging into implementation details of the system APIs always a good place to start
  33. Get familiar with GetComponentsIndexed()
  34. IFF if and only if
  35. At a high level, I have three sections to this discussion First, we&apos;ll talk about our purpose here. We&apos;ll discuss the problem we&apos;re trying to solve, and my approach to a solution Second, we&apos;ll talk about details of my solution, which I call the Dynamic Component System. We&apos;ll discuss features of the system, and why it&apos;s a good solution And third, we&apos;ll dig into implementation details of the system, Using a few systems of dynamic components for illustration purposes
  36. x Script Events are Components Possibly related to a Game Object, but Hosted by the Script Event System Allocated on-demand from Lua scripts When specified conditions are met, callback to script Two modes of testing for satisfaction: Some event types are updated automatically by the Dynamic Component System, and poll their conditions Other event types are notified of occasions during gameplay that may cause them to become satisfied
  37. Types are registered through the DynamicComponent::TypeRegistrar. The registrar is responsible for keeping track of the types registered with the system, Their base classes for testing which types implement which interfaces And during which update stages each type wants to be updated by the DCS
  38. e.g. Say the ScriptEventSystem just has a base type and two concrete event types. The base class is a component type named ScriptEvent.  We&apos;ll register two component type that are subclass of ScriptEvent To illustrate type registration, one will be notified, and one will be an event that updates both on PPU and asynchronously, e.g. on an SPU.  So we&apos;ll use LocationEvent for example. Upon system initialization, it registers both types LocationEvents update on the SPU during PreUpdate to poll various conditions for satisfaction.  It&apos;ll stash the results  back in the component LocationEvents also update on the PPU during PostUpdate for an opportunity to invoke script callbacks if they&apos;re satisfied Note, for even better performance, polling components don&apos;t need to update on PPU at all.  If SPU job determines that an event is satisfied, it can add the component to a shared &quot;invoke list&quot; to be processed after all ScriptEvents are updated. That way, only satisfied events will touch the PPU on any given frame.
  39. At a high level, I have three sections to this discussion First, we&apos;ll talk about our purpose here. We&apos;ll discuss the problem we&apos;re trying to solve, and my approach to a solution Second, we&apos;ll talk about details of my solution, which I call the Dynamic Component System. We&apos;ll discuss features of the system, and why it&apos;s a good solution And third, we&apos;ll dig into implementation details of the system, Using a few systems of dynamic components for illustration purposes
  40. NavComponents are hosted by Game Objects (usually Bots) to query the navigation database (mesh + dynamic obstructors) Updated by the Navigation system, not automatically by the Dynamic Component System For navigation-specific load balancing Interesting initialization idiom
  41. WTF is a prius? In Dynamic Component parlance, a prius is, &quot;A lightweight vehicle for transporting initialization data.&quot; Opportunity to pass runtime or design-time data to a component instance. Pirus is simply passed to the initialization method of a component instance upon allocation. But is that safe!?! Component must cast to an assumed type!
  42. WTF is a prius? In Dynamic Component parlance, a prius is, &quot;A lightweight vehicle for transporting initialization data.&quot; Opportunity to pass runtime or design-time data to a component instance. Pirus is simply passed to the initialization method of a component instance upon allocation. But is that safe!?! Component must cast to an assumed type!
  43. Interesting initialization idiom A NavQuery is the Prius for a NavComponent NavQuery::Submit() allocates a NavComponent, and passes itself as the prius.
  44. Obviously highly simplified, but meant to convey the point that that a Nav::Query is a prius, whose Submit() method returns the result of DynamicComponent::Allocate(),passing itself as void* prius.
  45. At a high level, I have three sections to this discussion First, we&apos;ll talk about our purpose here. We&apos;ll discuss the problem we&apos;re trying to solve, and my approach to a solution Second, we&apos;ll talk about details of my solution, which I call the Dynamic Component System. We&apos;ll discuss features of the system, and why it&apos;s a good solution And third, we&apos;ll dig into implementation details of the system, Using a few systems of dynamic components for illustration purposes
  46. x Hosted by Game Object that fired the Shot Completely replace the Projectile type of GameObject Two DynamicComponent Type hierarchies: Shot represents a state machine Don&apos;t update They are notified of events by their current ShotAction(s) ShotActions represent the states of a Shot Shared among different Shot types Automatically &amp; asynchronously updated by the Dynamic Component System
  47. The ShotMoveForward component type has different declarations on the PPU and on an SPU On the PPU, it is a polymorphic type, derived from ShotAction On the SPU, however, it is a POD type This allows us to operate on instances in an object-oriented way on the PPU, without a need to fix-up vtables in a different address space Note that m_location is the first member of ShotMoveForward on SPU, whereas m_next_location is a member of the base class ShotAction on the PPU.
  48. &quot;Sentinel&quot; data member identifies start of SPU instance This is achieved by placing a &quot;sentinel&quot; in the base class declaration identifying where an instance of the class begins when being DMA&apos;d to an SPU. The sentinel is a zero-sized array member 
  49. What we&apos;ve discussed First, we talked about our purpose here. We discussed the problem we wre trying to solve, and my approach to a solution Second, we talked about details of my solution, which I call the Dynamic Component System. We discussed features of the system, and why it&apos;s a good solution And third, we dug into implementation details of the system, Using a few systems of dynamic components for illustration purposes
  50. What we&apos;ve discussed First, we talked about our purpose here. We discussed the problem we wre trying to solve, and my approach to a solution Second, we talked about details of my solution, which I call the Dynamic Component System. We discussed features of the system, and why it&apos;s a good solution And third, we dug into implementation details of the system, Using a few systems of dynamic components for illustration purposes
  51. What we&apos;ve discussed First, we talked about our purpose here. We discussed the problem we wre trying to solve, and my approach to a solution Second, we talked about details of my solution, which I call the Dynamic Component System. We discussed features of the system, and why it&apos;s a good solution And third, we dug into implementation details of the system, Using a few systems of dynamic components for illustration purposes
  52. Closing thoughts. Tricky aspect: components that share data or otherwise communicate 2 options: Select one to own the data, other references through owner by resolving handle E.g. ShotActions call into Shot to notify of events Scatter-gather idiom PU update stages gather inputs for &amp; scatter outputs from SPU processes Involves copying Better for async processing