game.system.Collision = (entitiesGrid) => {
  const update = (elapsedTime, entities, changedIds) => {
    const thisChangedIds = new Set();
    for (let entity of Object.keys(entities).map((id) => entities[id])) {
      if (entity.hasComponent("controllable") && entity.hasComponent("gridPosition") && entity.hasComponent("momentum")) {
        const momentum = unitize(entity.components.momentum);

        let found;
        const proposed = {x: entity.components.gridPosition.x + momentum.dx, y: entity.components.gridPosition.y + momentum.dy};
        const entitiesToPush = [];
        let wall = false;
        do {
          const proposedClampedInBounds = clamp(proposed, game.config.xDim-1, game.config.yDim-1);
          if (!equivalence(proposed, proposedClampedInBounds)) {
            break;
          }

          found = false;

          const entitiesInCell = entitiesGrid[proposed.y][proposed.x];

          for (let next of entitiesInCell.values()) {
            if (next.hasComponent("stop")) {
              wall = next;
              found = false;
              break;
            }
            if (next.hasComponent("pushable")) {
              entitiesToPush.push(next);
              found = true;
            }
          }

          proposed.x += momentum.dx;
          proposed.y += momentum.dy;
        } while(found);

        if (wall) {
          entity.removeComponent("momentum");
        } else {
          entitiesToPush.map((e) => {
//            const particles = game.createBorderParticles({
//              colors: ["#16f7c9", "#0d6e5a", "#2fa18a", "#48cfb4", "#58877d", "#178054", "#2cdb92"],
//              maxSpeed: 0.20,
//              minRadius: 1,
//              maxRadius: 3,
//              minLife: 100,
//              maxLife: 300,
//              minAmount: 20,
//              maxAmount: 50,
//            });
//            particles.addComponent(game.components.Position(e.components.position));
//            particles.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
//            game.entities[particles.id] = particles;
            e.addComponent(game.components.Momentum({...momentum}))
          });
        }
      }
    }
    return thisChangedIds;
  };
  return { update };
};