public PlanetData Generate(float difficultySetting)
    {
        PlanetData data = new PlanetData();
        PlanetDifficultyModifiers difficultyModifiers
            = new PlanetDifficultyModifiers(difficultySetting);

        DungeonRoom currentRoom = null;
        int         keyLevel    = 1;

        //rule 1 -	Create starter room
        DungeonRoom startRoom = new StartRoom(IntPair.zero, null);

        data.AddRoom(startRoom);
        data.startRoom = startRoom;

        //rule 2 -	"Current Room" is starter room
        currentRoom = data.startRoom;

        //rule 7 -	Repeat steps 3 - 6 Y amount of times.
        int branchCount = Mathf.Max(1, Random.Range(
                                        difficultyModifiers.minBranchCount,
                                        PlanetDifficultyModifiers.MAX_BRANCH_COUNT));

        for (int j = 0; j < branchCount; j++)
        {
            //rule 3 -	Create a single branch from the "Current room" until X rooms have been
            //			created. Branch can't overlap with existing rooms. If branch meets a dead
            //			end, end the branch.
            int branchLength = Mathf.Max(1,
                                         Random.Range(difficultyModifiers.minBranchLength, difficultyModifiers.maxBranchLength));
            for (int i = 0; i < branchLength; i++)
            {
                DungeonRoom newRoom = CreateRandomExit(data, currentRoom, false,
                                                       keyLevel, false, false, difficultyModifiers);
                if (newRoom == currentRoom)
                {
                    break;
                }
                currentRoom = newRoom;
            }

            //rule 4 -	Place a key at the end of that branch
            currentRoom.AddKey(keyLevel);

            //rule 5 -	Create a locked exit to a new room from any existing room except the end of
            //			that branch.
            List <DungeonRoom> existingRooms = data.GetRooms();
            DungeonRoom        lockRoom      = currentRoom;
            do
            {
                int randomIndex = Random.Range(0, existingRooms.Count);
                lockRoom = existingRooms[randomIndex];
            } while (lockRoom == currentRoom || lockRoom.ExitCount == 4);
            lockRoom = CreateRandomExit(data, lockRoom, true,
                                        keyLevel, j == branchCount - 1, false, difficultyModifiers);
            keyLevel++;

            //rule 6 -	"Current room" is the new room on the other side of the locked exit
            currentRoom = lockRoom;
        }

        //rule 8 -	"Current room" is the final room
        data.finalRoom = currentRoom;

        //rule 9 -	Create "Dead end" branches Z times of X length from any room except the boss
        //			room.
        branchCount = Mathf.Max(0, Random.Range(difficultyModifiers.minDeadEndCount, difficultyModifiers.maxDeadEndCount));
        for (int i = 0; i < branchCount; i++)
        {
            List <DungeonRoom> existingRooms = data.GetRooms();
            DungeonRoom        deadEndStart  = null;
            do
            {
                int randomIndex = Random.Range(0, existingRooms.Count);
                deadEndStart = existingRooms[randomIndex];
            } while (deadEndStart == data.finalRoom || deadEndStart.ExitCount == 4);
            currentRoom = deadEndStart;

            int branchLength = Mathf.Max(1,
                                         Random.Range(difficultyModifiers.minBranchLength, difficultyModifiers.maxBranchLength));
            for (int j = 0; j < branchLength; j++)
            {
                DungeonRoom newRoom = CreateRandomExit(data, currentRoom, false,
                                                       keyLevel, false, j == branchLength - 1, difficultyModifiers);
                if (newRoom == currentRoom)
                {
                    break;
                }
                currentRoom = newRoom;
            }
        }

        for (int i = 0; i < data.GetRoomCount(); i++)
        {
            data.GetRooms()[i].GenerateContent();
        }

        for (int i = 0; i < data.GetRoomCount(); i++)
        {
            data.GetRooms()[i].GenerateOuterWalls();
        }

        return(data);
    }