title: Entity-Component System : fear of losing type & readability
body: <p>I have a Entity-Component System.      </p>
  
  <p><strong>Components</strong> : classes with data, but have no complex function<br>
  <strong>Entity</strong> : integer + list of Components (&lt;=1 instance per type per entity)<br>
  <strong>Systems</strong> : a lot of function with minimum data, do complex game logic</p>
  
  <p>Here is a sample.  A bullet entity <code>pewpew</code> is exploded, so it will be set to be invisible (at <code>#2</code>):-</p>
  
  <pre><code>class Component_Projectile : public ComponentBase{
      public: GraphicObject* graphicObject=nullptr;     //#1
      public: Entity whoCreateMe=nullptr;
      public: Entity targetEnemy=nullptr;
      //.... other fields ....
  };
  class System_Projectile : public SystemBase {
      public: void explodeDamage(Entity pewpew){ //called every time-step
          Pointer&lt;Component_Projectile&gt; comPro=pewpew;
          comPro-&gt;graphicObject-&gt;setVisible(false);     //#2
          //.... generate some cool particles, damage surrounded object, etc
      }
      //.... other functions ....
  };
  </code></pre>
  
  <p>It works OK.</p>
  
  <h1>New Version</h1>
  
  <p>Half year later, I realized that my architecture looks inconsistent.     </p>
  
  <ul>
  <li>I cache all <code>game-logic object</code> using <code>Entity</code>.     </li>
  <li>But cache <code>Physic Object</code> and <code>Graphic Object</code> by direct pointer. (e.g. <code>#1</code>)</li>
  </ul>
  
  <p><strong>I have a crazy idea :</strong><br>
  <code>Physic Object</code> and <code>Graphic Object</code> should also be <code>game-logic object</code>!<br>
  They should be encapsulated into <code>Entity</code>.</p>
  
  <p>Now the code will be (the change is marked with <code>#1</code> and <code>#2</code>):-</p>
  
  <pre><code>class Component_Projectile : public ComponentBase{
      public: Entity graphicObject=nullptr;                         //#1
      public: Entity whoCreateMe=nullptr;
      public: Entity targetEnemy=nullptr;
      //.... other fields ....
  };
  class System_Projectile : public SystemBase {
      public: void explodeDamage(Entity pewpew){ //called every time-step
          Pointer&lt;Component_Projectile&gt; comPro=pewpew;
          system_graphic-&gt;setVisible(comPro-&gt;graphicObject,false);  //#2
          //.... generate some cool particles, damage surrounded object, etc
      }
      //.... other functions ....
  };
  </code></pre>
  
  <p>After playing them for a week, I can conclude pro/cons of this approach as below :-</p>
  
  <h2><strong>Advantage</strong></h2>
  
  <p><strong>1. Drastically reduce couple between game logic VS graphic-engine/physic-engine</strong></p>
  
  <p>All graphics-specific function is now encapsulated inside 1-3 systems.<br>
  No other game systems (e.g. <code>System_Projectile</code>) refer to the hardcode type e.g. <code>GraphicObject</code>.      </p>
  
  <p><strong>2. Dramatically increase flexibility in design</strong></p>
  
  <p>Old vanilla graphic object is not just a graphic object anymore!      </p>
  
  <p>I can change it to something else, especially add special feature that is totally insane / too specific for physic/graphic engine, e.g.    </p>
  
  <ul>
  <li>rainbow blinking graphic</li>
  <li>strange gravity, magnet</li>
  <li>swap in/out many physic-object type in the same Entity (not sure)      </li>
  </ul>
  
  <p><strong>3. Reduce compile time</strong><br>
  It is accidentally become a pimpl idiom.<br>
  For example, <code>System_Projectile</code> don't have to <code>#include "GraphicObject.h"</code> any more.         </p>
  
  <h2><strong>Disadvantage</strong></h2>
  
  <p><strong>1. I have to encapsulate many graphic/physic-object's functions.</strong><br>
  For example, </p>
  
  <pre><code>system_graphic-&gt;setVisible(comPro-&gt;graphicObject,false);
  </code></pre>
  
  <p>is implemented as  </p>
  
  <pre><code>public: void setVisible(Entity entity,bool visible){
      entity.getComponent&lt;Graphic_Component&gt;()-&gt;underlying-&gt;setVisible(visible);
  }
  </code></pre>
  
  <p>It is tedious, but not a very hard work.<br>
  It can be partially alleviated by <code>&lt;...&gt;</code>.     </p>
  
  <p><strong>2. Performance is (only) little bit worse.</strong><br>
  Need a few additional indirection.</p>
  
  <p><strong>3. Code is less readable.</strong><br>
  The new version is harder to read.</p>
  
  <pre><code>comPro-&gt;graphicObject-&gt;setVisible(false);                //old version
  system_graphic-&gt;setVisible(comPro-&gt;graphicObject,false); //new version
  </code></pre>
  
  <p><strong>4. Losing type + <code>Ctrl+space</code> is less usable</strong><br>
  In old version, I can easily <code>ctrl+space</code> in this code :-</p>
  
  <pre><code>comPro-&gt;graphicObject-&gt; (ctrl+space)
  </code></pre>
  
  <p>It is now harder.  I have to think which system I want to call.</p>
  
  <pre><code>system_(ctrl+space)graphic-&gt;(ctrl+space)setVisible
  </code></pre>
  
  <h1><strong>Question</strong></h1>
  
  <p>In most code location, the advantage overcome the disadvantage, so I decided I will use the new version.    </p>
  
  <p>How to alleviate the disadvantages, especially number 3 and 4?<br>
  Design-pattern?  C++ magic?<br>
  I may use Entity-Component System in a wrong way. (?)      </p>