@Override
 public void handle(Packet packet) {
   if (packet instanceof StartGamePacket) {
     if (!isServer) {
       StartGamePacket sgPacker = (StartGamePacket) packet;
       synchronizer.onStartGamePacket(sgPacker);
       TitleMenu.difficulty = DifficultyList.getDifficulties().get(sgPacker.getDifficulty());
       createLevel(sgPacker.getLevelFile(), TitleMenu.defaultGameMode);
     }
   } else if (packet instanceof TurnPacket) {
     synchronizer.onTurnPacket((TurnPacket) packet);
   } else if (packet instanceof StartGamePacketCustom) {
     if (!isServer) {
       StartGamePacketCustom sgPacker = (StartGamePacketCustom) packet;
       synchronizer.onStartGamePacket((StartGamePacket) packet);
       TitleMenu.difficulty = DifficultyList.getDifficulties().get(sgPacker.getDifficulty());
       level = sgPacker.getLevel();
       paused = false;
       initLevel();
     }
   } else if (packet instanceof PingPacket) {
     PingPacket pp = (PingPacket) packet;
     synchronizer.onPingPacket(pp);
     if (pp.getType() == PingPacket.TYPE_ACK) {
       addToLatencyCache(pp.getLatency());
     }
   }
 }
 @Override
 public void handle(Packet packet) {
   if (packet instanceof StartGamePacket) {
     if (!isServer) {
       StartGamePacket sgPacker = (StartGamePacket) packet;
       synchronizer.onStartGamePacket(sgPacker.getGameSeed());
       TitleMenu.difficulty = DifficultyList.getDifficulties().get(sgPacker.getDifficulty());
       createLevel(sgPacker.getLevelFile());
     }
   } else if (packet instanceof TurnPacket) {
     synchronizer.onTurnPacket((TurnPacket) packet);
   } else if (packet instanceof StartGamePacketCustom) {
     if (!isServer) {
       StartGamePacketCustom sgPacker = (StartGamePacketCustom) packet;
       synchronizer.onStartGamePacket(sgPacker.getGameSeed());
       TitleMenu.difficulty = DifficultyList.getDifficulties().get(sgPacker.getDifficulty());
       level = sgPacker.getLevel();
       paused = false;
       initLevel();
     }
   }
 }
  private void tick() {
    // Not-In-Focus-Pause
    if (this.isFocusOwner() && level != null) {
      paused2 = false;
    }

    if (!this.isFocusOwner() && level != null) {
      keys.release();
      mouseButtons.releaseAll();
      if (!paused && !paused2) {
        PauseCommand pauseCommand = new PauseCommand(true);
        synchronizer.addCommand(pauseCommand);
        paused2 = true;
      }
    }
    if (isMultiplayer) {
      tickChat();
    }

    if (requestToggleFullscreen || keys.fullscreen.wasPressed()) {
      requestToggleFullscreen = false;
      setFullscreen(!fullscreen);
    }

    if (level != null && level.victoryConditions != null) {
      if (level.victoryConditions.isVictoryConditionAchieved()) {
        addMenu(new WinMenu(GAME_WIDTH, GAME_HEIGHT, level.victoryConditions.playerVictorious()));
        level = null;
        return;
      }
    }

    if (packetLink != null) {
      packetLink.tick();
    }

    mouseButtons.setPosition(getMousePosition());
    if (!menuStack.isEmpty()) {
      menuStack.peek().tick(mouseButtons);
    }
    if (mouseMoved) {
      mouseMoved = false;
      mouseHideTime = 0;
      if (mouseButtons.mouseHidden) {
        mouseButtons.mouseHidden = false;
      }
    }
    if (mouseHideTime < 60) {
      mouseHideTime++;
      if (mouseHideTime == 60) {
        mouseButtons.mouseHidden = true;
      }
    }

    if (level == null) {
      mouseButtons.tick();
    } else if (level != null) {
      if (synchronizer.preTurn()) {
        synchronizer.postTurn();

        for (int index = 0; index < mouseButtons.currentState.length; index++) {
          boolean nextState = mouseButtons.nextState[index];
          if (mouseButtons.isDown(index) != nextState) {
            synchronizer.addCommand(new ChangeMouseButtonCommand(index, nextState));
          }
        }

        synchronizer.addCommand(
            new ChangeMouseCoordinateCommand(
                mouseButtons.getX(), mouseButtons.getY(), mouseButtons.mouseHidden));

        mouseButtons.tick();
        for (MouseButtons sMouseButtons : synchedMouseButtons) {
          sMouseButtons.tick();
        }

        if (!paused) {
          for (int index = 0; index < keys.getAll().size(); index++) {
            Keys.Key key = keys.getAll().get(index);
            boolean nextState = key.nextState;
            if (key.isDown != nextState) {
              synchronizer.addCommand(new ChangeKeyCommand(index, nextState));
            }
          }

          keys.tick();
          for (Keys skeys : synchedKeys) {
            skeys.tick();
          }

          if (keys.pause.wasPressed()) {
            keys.release();
            mouseButtons.releaseAll();
            synchronizer.addCommand(new PauseCommand(true));
          }

          level.tick();
        }

        // every 4 minutes, start new background music :)
        if (System.currentTimeMillis() / 1000 > nextMusicInterval) {
          nextMusicInterval = (System.currentTimeMillis() / 1000) + 4 * 60;
          soundPlayer.startBackgroundMusic();
        }

        if (keys.screenShot.isDown) {
          takeScreenShot();
        }
      }
    }

    if (createServerState == 1) {
      createServerState = 2;

      synchronizer = new TurnSynchronizer(MojamComponent.this, packetLink, localId, 2);

      clearMenus();
      createLevel(TitleMenu.level, TitleMenu.defaultGameMode);

      synchronizer.setStarted(true);
      if (TitleMenu.level.vanilla) {
        packetLink.sendPacket(
            new StartGamePacket(
                TurnSynchronizer.synchedSeed,
                TitleMenu.level.getUniversalPath(),
                DifficultyList.getDifficultyID(TitleMenu.difficulty)));
      } else {
        packetLink.sendPacket(
            new StartGamePacketCustom(
                TurnSynchronizer.synchedSeed,
                level,
                DifficultyList.getDifficultyID(TitleMenu.difficulty)));
      }
      packetLink.setPacketListener(MojamComponent.this);
    }
  }
  private void tick() {

    if (packetLink != null) {
      packetLink.tick();
    }

    mouseButtons.setPosition(getMousePosition());
    if (!menuStack.isEmpty()) {
      menuStack.peek().tick(mouseButtons);
    }
    if (mouseMoved) {
      mouseMoved = false;
      mouseHideTime = 0;
      if (mouseHidden) {
        mouseHidden = false;
      }
    }
    if (mouseHideTime < 60) {
      mouseHideTime++;
      if (mouseHideTime == 60) {
        mouseHidden = true;
      }
    }
    mouseButtons.tick();

    if (level != null) {
      if (synchronizer.preTurn()) {
        synchronizer.postTurn();

        if (!paused) {
          for (int index = 0; index < keys.getAll().size(); index++) {
            Keys.Key key = keys.getAll().get(index);
            boolean nextState = key.nextState;
            if (key.isDown != nextState) {
              synchronizer.addCommand(new ChangeKeyCommand(index, nextState));
            }
          }

          keys.tick();
          for (Keys skeys : synchedKeys) {
            skeys.tick();
          }

          if (keys.pause.wasPressed()) {
            keys.release();
            synchronizer.addCommand(new PauseCommand(true));
          }

          if (keys.fullscreen.wasPressed()) {
            setFullscreen(!fullscreen);
          }

          // if mouse is in use, update player orientation before level tick
          if (!mouseHidden) {

            // update player mouse, in world pixels relative to
            // player
            player.setAimByMouse(
                ((mouseButtons.getX() / SCALE) - (screen.w / 2)),
                (((mouseButtons.getY() / SCALE) + 24) - (screen.h / 2)));
          } else {
            player.setAimByKeyboard();
          }

          level.tick();
        }

        // every 4 minutes, start new background music :)
        if (System.currentTimeMillis() / 1000 > nextMusicInterval) {
          nextMusicInterval = (System.currentTimeMillis() / 1000) + 4 * 60;
          soundPlayer.startBackgroundMusic();
        }

        if (keys.screenShot.isDown) {
          takeScreenShot();
        }
      }
    }

    if (createServerState == 1) {
      createServerState = 2;

      synchronizer = new TurnSynchronizer(MojamComponent.this, packetLink, localId, 2);

      clearMenus();
      createLevel(TitleMenu.level);

      synchronizer.setStarted(true);
      if (TitleMenu.level.vanilla) {
        packetLink.sendPacket(
            new StartGamePacket(
                TurnSynchronizer.synchedSeed,
                TitleMenu.level.getUniversalPath(),
                DifficultyList.getDifficultyID(TitleMenu.difficulty)));
      } else {
        packetLink.sendPacket(
            new StartGamePacketCustom(
                TurnSynchronizer.synchedSeed,
                level,
                DifficultyList.getDifficultyID(TitleMenu.difficulty)));
      }
      packetLink.setPacketListener(MojamComponent.this);
    }
  }