@Override
  protected void onStart() {
    super.onStart();

    em = new EntityManager();
    MetaEntity.defaultEntityManager = em;
    Game game = new Game(em);

    /** create the surface + thread */
    SurfaceViewThePit surfaceView = new SurfaceViewThePit(this, game);
    RenderSystemSimpleDrawable renderSystem = new RenderSystemSimpleDrawable(em, surfaceView, game);
    MainRunThread runGameThread = new MainRunThread(this, em, surfaceView, renderSystem);
    runGameThread.loadAllCoreSubSystems();

    // runGameThread.setGameResult( gameToStart );
    SubsystemTouchHandler systemTh = new SubsystemTouchHandler(em);
    runGameThread.orderedSubSystems.addLast(systemTh); // MUST be before the Collision Subsystem
    TouchListenerPlayerMovement thv = new TouchListenerPlayerMovement(systemTh);

    SubsystemGhosts systemGhosts = new SubsystemGhosts(em, game);
    runGameThread.orderedSubSystems.addLast(systemGhosts);

    SubsystemMovementAndCollision systemCollision =
        new SubsystemMovementAndCollision(em, renderSystem);
    runGameThread.orderedSubSystems.addLast(systemCollision);

    SubsystemLighting systemLighting = new SubsystemLighting(em, game);
    runGameThread.orderedSubSystems.addLast(systemLighting);

    SubsystemTriggers systemTriggers = new SubsystemTriggers(this, em, game);
    runGameThread.orderedSubSystems.addLast(systemTriggers);

    surfaceView.setOnTouchListener(thv);
    surfaceView.thread = runGameThread;
    Log.i(getClass().getSimpleName(), "initialized thread and surface");

    /**
     * Finally ... tell the game that the ES is now valid, it's ship reference is OK, and it can do
     * game-setup
     */
    game.preSetupGame();
    renderSystem.shiftCanvasToKeepPositionOnScreen(
        new CPosition(
            game.initialPlayerLocation.x,
            game.initialPlayerLocation.y,
            game.mazeCellWidth,
            game.mazeCellHeight));

    // turn off the window's title bar
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow()
        .setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(surfaceView);
  }
  public void loseGame() {
    final GameBoard boardView = (GameBoard) this.findViewById(R.id.gameBoard);

    game.reInitGame();

    boardView.setGame(game);
    boardView.invalidate();
  }
  @Override
  protected void onStop() {
    SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();

    editor.putInt("level", this.level);
    editor.putString("map", game.getLabyrinth().getJsonMap());
    editor.putString("howdy", game.getJsonHowdy());

    String allDoneLevelsString = "";

    for (String s : allDoneLevels) {
      allDoneLevelsString += s + ",";
    }

    if (allDoneLevelsString.length() > 0) {
      editor.putString(
          "doneLevels", allDoneLevelsString.substring(0, allDoneLevelsString.length() - 1));
    }

    editor.commit();

    super.onStop();
  }
  public void nextLevel() {
    boolean loaded = false;
    final GameBoard boardView = (GameBoard) this.findViewById(R.id.gameBoard);
    this.level++;

    AssetManager am = getResources().getAssets();

    try {
      List<String> allTutoLevels =
          new LinkedList<String>(Arrays.asList(am.list("levels/tutorial")));

      // if(addMsg){
      //    allTutoLevels.addAll(Arrays.asList(am.list("msg")));
      // }

      Log.d(TAG, allTutoLevels.toString());

      for (String name : allTutoLevels) {
        if (name.startsWith(this.level + ".")) {
          BufferedReader br =
              new BufferedReader(new InputStreamReader(am.open("levels/tutorial/" + name)));
          String line;
          String levelJSON = "";

          while ((line = br.readLine()) != null) {
            levelJSON += line + "\n";
          }

          br.close();

          game.initGame(
              levelJSON, boardView.getMeasuredWidth() / 60, boardView.getMeasuredHeight() / 60);
          loaded = true;
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }

    if (!loaded) {
      Random r = new Random();

      List<String> allLevels = new ArrayList<>();

      try {
        allLevels = Arrays.asList(am.list("levels"));
      } catch (IOException e) {
      }

      if (r.nextBoolean() && !allLevels.isEmpty() && allLevels.size() != allDoneLevels.size()) {
        try {
          int nLevel;
          do {
            nLevel = r.nextInt(allLevels.size());
          } while (allDoneLevels.contains(allLevels.get(nLevel)));

          String name = allLevels.get(nLevel);
          BufferedReader br = new BufferedReader(new InputStreamReader(am.open("levels/" + name)));

          String line;
          String levelJSON = "";

          while ((line = br.readLine()) != null) {
            levelJSON += line + "\n";
          }

          br.close();

          allDoneLevels.add(name);

          game.initGame(
              levelJSON, boardView.getMeasuredWidth() / 60, boardView.getMeasuredHeight() / 60);
        } catch (IOException e) {
          this.game.initGame(
              level, boardView.getMeasuredWidth() / 60, boardView.getMeasuredHeight() / 60);
        }
      } else {
        this.game.initGame(
            level, boardView.getMeasuredWidth() / 60, boardView.getMeasuredHeight() / 60);
      }
    }

    // am.close();

    boardView.setGame(this.game);
    boardView.invalidate();
    boardView.getHowdyShadeView().invalidate();

    Toast.makeText(this, this.level + "", Toast.LENGTH_SHORT).show();

    Log.i(
        TAG,
        "Max tiles : "
            + (boardView.getMeasuredWidth() / 60) * (boardView.getMeasuredHeight() / 60));
  }