Successfully reported this slideshow.

Game architecture is different

7,216 views

Published on

Presented at try{harder} 2011 this presentation compared building a game using an entity framework (Ember) to building the same game using an MVC framework (Robotlegs) and then looked at why the entity framework is better suited to developing games.

Game architecture is different

  1. 1. Game architecture is differenttry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  2. 2. Is game architecture different?try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  3. 3. Asteroidstry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  4. 4. Conclusion: Entity systems are bettertry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  5. 5. Why?try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  6. 6. Code statistics Entities (Ember) MVC (Robotlegs) 38 classes 30 classes 1047 lines of code 1092 lines of code 26710 characters of code 25915 characters of codetry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  7. 7. Robotlegs Mediators Model Commands AsteroidsMediator SpaceshipMediator GameState CreateAsteroid AsteroidMediator GameSize CreateBullet BulletMediator Spaceship CreateSpaceship SpaceshipContainer RouteInput Views Asteroid StartGame Asteroids AsteroidContainer StartGame SpaceshipView Bullet Update AsteroidView BulletContainer BulletViewtry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  8. 8. Ember Components Nodes Systems (Processes) Spaceship MotionControlNode ProcessManager Asteroid GunControlNode GameManager Views Gun BulletAgeNode MotionControlSystem SpaceshipView Bullet MovementNode GunControlSystem AsteroidView GameState SpaceshipCollisionNode BulletAgeSystem BulletView Position AsteroidCollisionNode MovementSystem Motion BulletCollisionNode CollisionSystem Display RenderNode RendersSystem MotionControls GunControlstry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  9. 9. Evolution of entity systemstry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  10. 10. The game looptry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  11. 11. function  update(  time:Number  ):void {    game.update(  time  );    spaceship.updateInputs(  time  );    for  each(  var  flyingSaucer:FlyingSaucer  in  flyingSaucers  )        flyingSaucer.updateAI(  time  );    spaceship.update(  time  );    for  each(  var  flyingSaucer:FlyingSaucer  in  flyingSaucers  )        flyingSaucer.update(  time  );    for  each(  var  asteroid:Asteroid  in  asteroids  )        asteroid.update(  time  );    for  each(  var  bullet:Bullet  in  bullets  )        bullet.update(  time  );    collisionManager.update(  time  );    spaceship.render();    for  each(  var  flyingSaucer:FlyingSaucer  in  flyingSaucers  )        flyingSaucer.render();    for  each(  var  asteroid:Asteroid  in  asteroids  )        asteroid.render();    for  each(  var  bullet:Bullet  in  bullets  )        bullet.render();try { harder } conference 2011 } ©Richard Lord 2011 - www.richardlord.net
  12. 12. Processes & Process Managertry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  13. 13. interface  IProcess {    function  start():Boolean;    function  update(  time:Number  ):void;    function  end():void; }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  14. 14. class  ProcessManager { private  var  processes:PrioritisedList; public  function  addProcess(  process:IProcess,  priority:int  ):Boolean  { if(  process.start()  )  { processes.add(  process,  priority  ); return  true; } return  false; } public  function  update(  time:Number  ):void  { for  each(  var  process:IProcess  in  processes  ) process.update(  time  ); } public  function  removeProcess(  process:IProcess  ):void  { process.end(); processes.remove(  process  ); }try { harder } conference 2011 } ©Richard Lord 2011 - www.richardlord.net
  15. 15. class  RenderProcess  implements  iProcess {    public  function  update(  time:Number  ):void  {        spaceship.render();        for  each(  var  flyingSaucer:FlyingSaucer  in  flyingSaucers  )            flyingSaucer.render();        for  each(  var  asteroid:Asteroid  in  asteroids  )            asteroid.render();        for  each(  var  bullet:Bullet  in  bullets  )            bullet.render();    } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  16. 16. interface  IRenderable {    function  render(); } class  RenderProcess  implements  IProcess {    private  var  targets:Vector.<IRenderable>;    public  function  update(  time:Number  ):void  {        for  each(  var  target:IRenderable  in  targets  )            target.render();    } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  17. 17. class  Spaceship  implements  IRenderable {    public  var  view:DisplayObject;    public  var  position:Point;    public  var  rotation:Number;    public  function  render():void  {        view.x  =  position.x;        view.y  =  position.y;        view.rotation  =  rotation;    } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  18. 18. class  Renderable  implements  IRenderable {    public  var  view:DisplayObject;    public  var  position:Point;    public  var  rotation:Number;    public  function  render():void  {        view.x  =  position.x;        view.y  =  position.y;        view.rotation  =  rotation;    } } class  Spaceship  extends  Renderable { }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  19. 19. Renderable Spaceship FlyingSaucer Asteroid Bullettry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  20. 20. interface  IMoveable {    function  move(); } class  MoveProcess  implements  IProcess {    private  var  targets:Vector.<IMoveable>;    public  function  update(  time:Number  ):void  {        for  each(  var  target:IMoveable  in  targets  )            target.move(  time  );    } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  21. 21. class  Moveable  implements  IMoveable {    public  var  position:Point;    public  var  rotation:Number;    public  var  velocity:Point;    public  var  angularVelocity:Number;    public  function  move(  time:Number  ):void  {        position.x  +=  velocity.x  *  time;        position.y  +=  velocity.y  *  time;        rotation  +=  angularVelocity  *  time;    } } class  Spaceship  extends  Moveable { }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  22. 22. class  Moveable  extends  Renderable  implements  IMoveable { //    public  var  position:Point; //    public  var  rotation:Number;    public  var  velocity:Point;    public  var  angularVelocity:Number;    public  function  move(  time:Number  ):void  {        position.x  +=  velocity.x  *  time;        position.y  +=  velocity.y  *  time;        rotation  +=  angularVelocity  *  time;    } } class  Spaceship  extends  Moveable { }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  23. 23. Renderable Moveable Spaceship FlyingSaucer Asteroid Bullettry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  24. 24. Moveable Renderable Spaceship FlyingSaucer Asteroid Bullettry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  25. 25. class  Renderable  implements  IRenderable class  Moveable  implements  IMoveable { {    public  var  view:DisplayObject;    public  var  position:Point;    public  var  position:Point;    public  var  rotation:Number;    public  var  rotation:Number;    public  var  velocity:Point;    public  var  angularVelocity:Number;    public  function  render():void  {        view.x  =  position.x;    public  function  move(  time:Number  ):void  {        view.y  =  position.y;        position.x  +=  velocity.x  *  time;        view.rotation  =  rotation;        position.y  +=  velocity.y  *  time;    }        rotation  +=  angularVelocity  *  time; }    } } class  Spaceship {    public  var  renderData:IRenderable;    public  var  moveData:IMoveable; }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  26. 26. interface  IRenderable interface  IMoveable { {    function  render();    function  move(); } } class  RenderProcess  implements  IProcess class  MoveProcess  implements  IProcess { {    private  var  targets:Vector.<IRenderable>;    private  var  targets:Vector.<IMoveable>;    public  function  update(time:Number):void{    public  function  update(time:Number):void  {        for  each(var  target:IRenderable  in  targets)        for  each(var  target:IMoveable  in  targets)            target.render();            target.move(  time  );    }    } } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  27. 27. public  function  createSpaceship(  time:Number  ):Spaceship  {    var  spaceship:Spaceship  =  new  Spaceship();    ...    renderProcess.addItem(  spaceship.renderData  );    moveProcess.addItem(  spaceship.moveData  );    ...    return  spaceship; }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  28. 28. class  Renderable  implements  IRenderable class  Moveable  implements  IMoveable { {    public  var  view:DisplayObject;    public  var  position:Point;    public  var  position:Point;    public  var  rotation:Number;    public  var  rotation:Number;    public  var  velocity:Point;    public  var  angularVelocity:Number;    public  function  render():void  {        view.x  =  position.x;    public  function  move(  time:Number  ):void  {        view.y  =  position.y;        position.x  +=  velocity.x  *  time;        view.rotation  =  rotation;        position.y  +=  velocity.y  *  time;    }        rotation  +=  angularVelocity  *  time; }    } } class  Spaceship {    public  var  renderData:IRenderable;    public  var  moveData:IMoveable; }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  29. 29. class  Renderable  implements  IRenderable class  Moveable  implements  IMoveable { {    public  var  display:DisplayComponent;    public  var  position:PositionComponent;    public  var  position:PositionComponent;    public  var  velocity:VelocityComponent;    public  function  render():void  {    public  function  move(  time:Number  ):void  {        display.view.x  =  position.x;        position.x  +=  velocity.velocityX  *  time;        display.view.y  =  position.y;        position.y  +=  velocity.velocityY  *  time;        display.view.rotation        position.rotation            =  position.rotation;            +=  velocity.angularVelocity  *  time;    }    } } } class  DisplayComponent  { class  VelocityComponent  {    public  var  view:DisplayObject;    public  var  velocityX:Number; }    public  var  velocityY:Number;    public  var  angularVelocity:Number; class  PositionComponent  { }    public  var  x:Number;    public  var  y:Number;    public  var  rotation:Number;try { harder } conference 2011 } ©Richard Lord 2011 - www.richardlord.net
  30. 30. class  Spaceship {    public  function  Spaceship()  {        moveData  =  new  MoveData(  new  PositionComponent(),  new  VelocityComponent()  );        renderData  =  new  RenderData(  new  DisplayComponent(),  moveData.position  );    } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  31. 31. class  Renderable  implements  IRenderable {    public  var  display:DisplayComponent;    public  var  position:PositionComponent;    public  function  render():void  {        display.view.x  =  position.x;        display.view.y  =  position.y;        display.view.rotation  =  position.rotation;    } } class  RenderProcess  implements  IProcess {    private  var  targets:Vector.<IRenderable>;    public  function  update(  time:Number  ):void  {        for  each(  var  target:IRenderable  in  targets  )            target.render();    } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  32. 32. class  RenderData {    public  var  display:DisplayComponent;    public  var  position:PositionComponent; } class  RenderProcess  implements  IProcess {    private  var  targets:Vector.<RenderData>;    public  function  update(  time:Number  ):void  {        for  each(  var  target:RenderData  in  targets  )  {            target.display.view.x  =  target.position.x;            target.display.view.y  =  target.position.y;            target.display.view.rotation  =  target.position.rotation;        }    } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  33. 33. class  Moveable  implements  IMoveable {    public  var  position:PositionComponent;    public  var  velocity:VelocityComponent;    public  function  move(  time:Number  ):void  {        position.x  +=  velocity.velocityX  *  time;        position.y  +=  velocity.velocityY  *  time;        position.rotation  +=  velocity.angularVelocity  *  time;    } } class  MoveProcess  implements  IProcess {    private  var  targets:Vector.<IMoveable>;    public  function  move(  time:Number  ):void  {        for  each(  var  target:Moveable  in  targets  )            target.move(  time  );    } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  34. 34. class  MoveData {    public  var  position:PositionComponent;    public  var  velocity:VelocityComponent; } class  MoveProcess  implements  IProcess {    private  var  targets:Vector.<MoveData>;    public  function  move(  time:Number  ):void  {        for  each(  var  target:MoveData  in  targets  )  {            target.position.x  +=  target.velocity.velocityX  *  time;            target.position.y  +=  target.velocity.velocityY  *  time;            target.position.rotation  +=  target.velocity.angularVelocity  *  time;        }    } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  35. 35. class  Spaceship  {    public  var  renderData:RenderData;    public  var  moveData:MoveData; }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  36. 36. class  Spaceship  {    public  var  renderData:RenderData; class  RenderData  {    public  var  moveData:MoveData;    public  var  display:DisplayComponent; }    public  var  position:PositionComponent; } class  MoveData  {    public  var  position:PositionComponent;    public  var  velocity:VelocityComponent; }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  37. 37. class  Spaceship  {    public  var  renderData:RenderData; class  RenderData  {    public  var  moveData:MoveData;    public  var  display:DisplayComponent; }    public  var  position:PositionComponent; } class  MoveData  {    public  var  position:PositionComponent; class  DisplayComponent  {    public  var  velocity:VelocityComponent;    public  var  view:DisplayObject; } } class  VelocityComponent  { class  PositionComponent  {    public  var  velocityX:Number;    public  var  x:Number;    public  var  velocityY:Number;    public  var  y:Number;    public  var  angularVelocity:Number;    public  var  rotation:Number; } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  38. 38. class  Spaceship  {    public  var  renderData:RenderData; class  RenderData  {    public  var  moveData:MoveData;    public  var  display:DisplayComponent; }    public  var  position:PositionComponent; } class  MoveData  {    public  var  position:PositionComponent; class  DisplayComponent  {    public  var  velocity:VelocityComponent;    public  var  view:DisplayObject; } } class  VelocityComponent  { class  PositionComponent  {    public  var  velocityX:Number;    public  var  x:Number;    public  var  velocityY:Number;    public  var  y:Number;    public  var  angularVelocity:Number;    public  var  rotation:Number; } } class  RenderProcess  implements  IProcess  { class  MoveProcess  implements  IProcess  {    private  var  targets:Vector.<RenderData>;    private  var  targets:Vector.<MoveData>; } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  39. 39. class  Spaceship  {    public  var  display:DisplayComponent; class  DisplayComponent  {    public  var  position:PositionComponent;    public  var  view:DisplayObject;    public  var  velocity:VelocityComponent; } } class  VelocityComponent  { class  PositionComponent  {    public  var  velocityX:Number;    public  var  x:Number;    public  var  velocityY:Number;    public  var  y:Number;    public  var  angularVelocity:Number;    public  var  rotation:Number; } } class  RenderData  {    public  var  display:DisplayComponent; class  MoveData  {    public  var  position:PositionComponent;    public  var  position:PositionComponent; }    public  var  velocity:VelocityComponent; } class  RenderProcess  implements  IProcess  { class  MoveProcess  implements  IProcess  {    private  var  targets:Vector.<RenderData>;    private  var  targets:Vector.<MoveData>; } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  40. 40. class  Entity  { class  DisplayComponent  {    public  var  data:Array;    public  var  view:DisplayObject; } } class  PositionComponent  {    public  var  x:Number; class  VelocityComponent  {    public  var  y:Number;    public  var  velocityX:Number;    public  var  rotation:Number;    public  var  velocityY:Number; }    public  var  angularVelocity:Number; } class  RenderData  {    public  var  display:DisplayComponent;    public  var  position:PositionComponent; class  MoveData  { }    public  var  position:PositionComponent;    public  var  velocity:VelocityComponent; } class  MoveProcess  implements  IProcess  { class  RenderProcess  implements  IProcess  {    private  var  targets:Vector.<MoveData>;    private  var  targets:Vector.<RenderData>; } }try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  41. 41. Entity systems are better (for games driven by a game loop)try { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  42. 42. Ember Components Nodes Systems (Processes) Spaceship MotionControlNode ProcessManager Asteroid GunControlNode GameManager Views Gun BulletAgeNode MotionControlSystem SpaceshipView Bullet MovementNode GunControlSystem AsteroidView GameState SpaceshipCollisionNode BulletAgeSystem BulletView Position AsteroidCollisionNode MovementSystem Motion BulletCollisionNode CollisionSystem Display RenderNode RendersSystem MotionControls GunControlstry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  43. 43. Robotlegs Mediators Model Commands AsteroidsMediator SpaceshipMediator GameState CreateAsteroid AsteroidMediator GameSize CreateBullet BulletMediator Spaceship CreateSpaceship SpaceshipContainer RouteInput Views Asteroid StartGame Asteroids AsteroidContainer StartGame SpaceshipView Bullet Update AsteroidView BulletContainer BulletViewtry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net
  44. 44. And now Ive run out of stuff to saytry { harder } conference 2011 ©Richard Lord 2011 - www.richardlord.net

×