class PlayerGames implements Iterable<PlayerGame>, Tickable {

    @Override
    public void tick() {
        List<PlayerGame> active = active();

        // по всем джойстикам отправили сообщения играм
        active.forEach(PlayerGame::quietTick);

        // если в TRAINING кто-то isWin то мы его относим на следующий уровень
        // если в DISPOSABLE уровнях кто-то shouldLeave то мы его перезагружаем - от этого он появится на другом поле
        // а для всех остальных, кто уже isGameOver - создаем новые игры на том же поле
        for (PlayerGame playerGame : active) {
            Game game = playerGame.getGame();
            String roomName = playerGame.getRoomName();

            MultiplayerType multiplayerType = playerGame.getGameType().getMultiplayerType();
            if (game.isGameOver()) {
                quiet(() -> {
                    JSONObject level = game.getSave();

                    // TODO ##2 попробовать какой-то другой тип с несколькими уровнями, а не только isTraining
                    if (game.isWin() && multiplayerType.isTraining()) {
                        level = LevelProgress.winLevel(level);
                        if (level != null) {
                            reload(game, roomName, level);
                            fireOnLevelChanged(playerGame);
                            return;
                        }
                    }

                    if (game.shouldLeave() && multiplayerType.isDisposable()) {
                        reload(game, roomName, level);
                        return;
                    }

                    game.newGame();
                });
            }
        }

        // собираем все уникальные борды
        // независимо от типа игры нам нужно тикнуть все
        //      но только те, которые не DISPOSABLE и одновременно
        //      недокомплектованные пользователями
        //      а так же котмнаты которых активны
        active.stream()
                .map(PlayerGame::getField)
                .distinct()
                .filter(spreader::isRoomStaffed)
                .forEach(GameField::quietTick);

        // ну и тикаем все GameRunner мало ли кому надо на это подписаться
        getGameTypes().forEach(GameType::quietTick);
    }

    public  PlayerGames();

}