ECS Event/Messaging implementation
My suggestions:

Move type_count from being a public member

type_count plays an important role in the event manager. Making such a crucial part of the event management system a publically accessible member variable seems risky to me.

I would make that accessible only as a protected member function.

struct BaseEvent
{
   virtual ~BaseEvent() {}
   protected:
      static size_t getNextType();
};

size_t BaseEvent::getNextType()
{
   static size_t type_count = 0;
   return type_count++;
}


Of course, change Event appropriately.

template &lt;typename EventType&gt;
struct Event : BaseEvent
{
   static size_t type()
   {
      static size_t t_type = BaseEvent::getNextType();
      return t_type;
   } //; You don't need this semi-colon. Remove it.
};


Change the implementation of EventManager to simply event classes

Instead of 

struct PLAYER_LVL_UP : Event&lt;PLAYER_LVL_UP&gt;
{ int new_level; };

struct PLAYER_HIT : Event&lt;PLAYER_HIT&gt;
{ int damage; };

struct COLLISION : Event&lt;COLLISION&gt;
{ Entity entity1; Entity entity2; };


it's cleaner to have:

struct PLAYER_LVL_UP
{ int new_level; };

struct PLAYER_HIT
{ int damage; };

struct COLLISION
{ Entity entity1; Entity entity2; };


You can accomplish that by updating EventManager to:

struct EventManager
{
   template &lt;class EventType&gt;
      using call_type = std::function&lt;void(const EventType&amp;)&gt;;

   template &lt;typename EventType&gt;
      void subscribe(call_type&lt;EventType&gt; callable)
      {
         // When events such as COLLISION don't derive
         // from Event, you have to get the type by 
         // using one more level of indirection.
         size_t type = Event&lt;EventType&gt;::type();
         if (type &gt;= m_subscribers.size())
            m_subscribers.resize(type+1);
         m_subscribers[type].push_back(CallbackWrapper&lt;EventType&gt;(callable));
      }

   template &lt;typename EventType&gt;
      void emit(const EventType&amp; event)
      {
         // Same change to get the type.
         size_t type = Event&lt;EventType&gt;::type();
         if (type &gt;= m_subscribers.size())
            m_subscribers.resize(type+1);

         // This a crucial change to the code.
         // You construct a temporary Event object by
         // using the EventType object and use Event.
         // This requires a change to Event, which follows below.
         Event&lt;EventType&gt; eventWrapper(event);
         for (auto&amp; receiver : m_subscribers[type])
            receiver(eventWrapper);

      }

   template &lt;typename EventType&gt;
      struct CallbackWrapper
      {
         CallbackWrapper(call_type&lt;EventType&gt; callable) : m_callable(callable) {}

         void operator() (const BaseEvent&amp; event) { 
          // The event handling code requires a small change too.
          // A reference to the EventType object is stored 
          // in Event. You get the EventType reference from the
          // Event and make the final call.
          m_callable(static_cast&lt;const Event&lt;EventType&gt;&amp;&gt;(event).event_); }

         call_type&lt;EventType&gt; m_callable;
      };

   std::vector&lt;std::vector&lt;call_type&lt;BaseEvent&gt;&gt;&gt; m_subscribers;
};


The updated Event class:

template &lt;typename EventType&gt;
struct Event : BaseEvent
{
   static size_t type()
   {
      static size_t t_type = BaseEvent::getNextType();
      return t_type;
   }
   Event(const EventType&amp; event) : event_(event) {}
   const EventType&amp; event_;
};