@Override
  protected void freeChunk(Point p) {
    int x = (int) p.getX() >> Chunk.BLOCKS.BITS;
    int y = (int) p.getY() >> Chunk.BLOCKS.BITS; // + SEALEVEL_CHUNK;
    int z = (int) p.getZ() >> Chunk.BLOCKS.BITS;

    if (y < 0 || y >= p.getWorld().getHeight() >> Chunk.BLOCKS.BITS) {
      return;
    }

    TIntSet column = initializedChunks.get(x, z);
    CompressedChunkMessage CCMsg;
    if (column != null) {
      column.remove(y);
      if (column.isEmpty()) {
        if (initializedChunks.remove(x, z) != null) {
          activeChunks.remove(x, z);
        }
        CCMsg = new CompressedChunkMessage(x, z, true, null, null, null, true);
      } else {
        CCMsg = new CompressedChunkMessage(x, z, false, null, null, null, true);
      }

      session.send(false, CCMsg);
    }
  }
  @Override
  public void preSnapshot() {
    super.preSnapshot();

    Long key;
    while ((key = this.emptyColumns.poll()) != null) {
      int x = IntPairHashed.key1(key);
      int z = IntPairHashed.key2(key);
      TIntSet column = initializedChunks.get(x, z);
      if (column.isEmpty()) {
        column = initializedChunks.remove(x, z);
        activeChunks.remove(x, z);
        session.send(
            false, new ChunkDataMessage(x, z, true, null, null, null, true, player.getSession()));
      }
    }
  }