title: Emitting events from Redux reducers
body: <p>I'm using <code>redux</code> as a state container in a simple shooter game. State is completely deterministic, the only input the system receives is user input (eg. a weapon was fired, etc).
  My problem is that I have to track (and process) certain events, that happen during the game (eg. something was destroyed, etc), and I'm not quite sure how to do that.
  My current solution is that the reducer maintains an <code>events</code> array in the current state, and every reducer just appends events to it.</p>
  
  <pre><code>FIRE_WEAPON+-+          FIRE_WEAPON+-+
               |                       |
               |                       |
             +-v--------+--------------v-------------&gt;
                        |
                        |
                        +-&gt;PLAYER_DESTROYED
  </code></pre>
  
  <p>Here the reduces receives two <code>FIRE_WEAPON</code> action, and should <em>"emit"</em> a <code>PLAYER_DESTROYED</code> event (right now, it is used to render an explosion there).</p>
  
  <p>The <a href="https://github.com/madbence/spacegame" rel="noreferrer">project</a> is open source, the reducer looks something like this (it's just pseudocode, but here is the <a href="https://github.com/madbence/spacegame/blob/22b28b74eb778fe1636078b0ed0b66d6cff2ca33/src/shared/game.js#L99-L150" rel="noreferrer">relevant game logic</a>):</p>
  
  <pre><code>// combine is just (f, g) =&gt; ((s, a) =&gt; g(f(s, a), a))
  const reducer = combine(
  
    // simulate world
    (state, action) =&gt; {
      while (state.time &lt; action.time) {
        state = evolve(state, delta); // evolve appends the happened in-game events to the state
      }
      return state;
    },
  
    // handle actual user input
    (state, action) =&gt; {
      return handleUserInput(state, action);
    }
  );
  
  const evolve = (state, delta) =&gt; {
    const events = [];
  
    // some game logic that does some `events.push(...)`
  
    return {
      ...state,
      time: state.time + delta,
      events: state.events.concat(events),
    };
  }
  </code></pre>
  
  <p>We can assume, that <code>handleUserInput</code> is a simple <code>x =&gt; x</code> identity function (it doesn't touch the <code>events</code> array).
  During <code>evolve</code>, I'd like to <em>"emit"</em> events, but since that would make <code>evolve</code> impure, I cannot do that.
  As I said, right now I'm doing this by storing the happened events in the state, but there might be a better way. Any suggestions?</p>
  
  <p>These <code>events</code> are used during rendering, which looks likes this:</p>
  
  <pre><code>let sprites = [];
  
  // `subscribe`d to store
  function onStateChange() {
    // `obsolete` removes old sprites that should not be displayed anymore
    // `toSprite` converts events to sprites, you can assume that they are just simple objects
    sprites = sprites.filter(obsolete).concat(store.getState().events.map(toSprite));
  }
  
  function render(state) {
    renderState(state);
    renderSprites(sprites);
  }
  </code></pre>
  
  <p>But later on I'd like use <code>events</code> on the server (the reducer described above runs on the server too), for calculating various stats (eg. enemies destroyed, etc.).</p>
  
  <p>Ps.: these <em>"emitted"</em> events have no influence on the state (they are totally unrelated), so I'm sure that they shouldn't be actions (because they would leave the state unchanged). They are processed after the reducer has finished, after that they can be dropped (the reducer always receives an empty <code>events</code> array).</p>