private void buildPerceptions() {
    playersToRemove.clear();

    /** We reset the cache at Perceptions */
    MessageS2CPerception.clearPrecomputedPerception();

    for (PlayerEntry entry : playerContainer) {
      try {
        // Before creating the perception we check the player is still there.
        if (entry.isTimeout()) {
          logger.info("Request (TIMEOUT) disconnection of Player " + entry.getAddress());
          playersToRemove.add(entry);
          continue;
        }

        if (entry.state == ClientState.GAME_BEGIN) {
          Perception perception = getPlayerPerception(entry);
          sendPlayerPerception(entry, perception, entry.object);
        }
      } catch (Exception e) {
        logger.error(
            "Removing player("
                + entry.clientid
                + ") because it caused a Exception while contacting it",
            e);
        playersToRemove.add(entry);
      }
    }

    for (PlayerEntry entry : playersToRemove) {
      logger.warn("RP Disconnecting entry: " + entry);
      netMan.disconnectClient(entry.channel);
    }
  }
  private void sendPlayerPerception(
      PlayerEntry entry, Perception perception, RPObject playerObject) {
    if (perception == null) {
      /** Until player enters game perception is null */
      return;
    }

    MessageS2CPerception messages2cPerception = new MessageS2CPerception(entry.channel, perception);

    stats.add("Perceptions " + (perception.type == 0 ? "DELTA" : "SYNC"), 1);

    /*
     * The perception is build of two parts: the general information and the
     * private information about our object. This private information
     * consists only of attributes that are not visible to every player but
     * the owner, because visible attributes are already stored in the
     * perception.
     */

    if (perception.type == Perception.SYNC) {
      RPObject copy = new RPObject();
      copy.fill(playerObject);
      if (!playerObject.isHidden()) {
        copy.clearVisible(true);
      }
      messages2cPerception.setMyRPObject(copy, null);
    } else {
      RPObject added = new RPObject();
      RPObject deleted = new RPObject();

      try {
        playerObject.getDifferences(added, deleted);
        if (!playerObject.isHidden()) {
          added.clearVisible(false);
          deleted.clearVisible(false);
        }

        if (added.size() == 0) {
          added = null;
        }

        if (deleted.size() == 0) {
          deleted = null;
        }
      } catch (Exception e) {
        logger.error("Error getting object differences", e);
        logger.error(playerObject);
        added = null;
        deleted = null;
      }
      messages2cPerception.setMyRPObject(added, deleted);
    }

    messages2cPerception.setClientID(entry.clientid);
    messages2cPerception.setPerceptionTimestamp(entry.getPerceptionTimestamp());
    messages2cPerception.setProtocolVersion(entry.getProtocolVersion());

    netMan.sendMessage(messages2cPerception);
  }