public PrototypeDungeonGenerator(AbstractDungeonStructure structure, int seed, GenerationParameters generationParameters = null)
        {
            _seed   = seed;
            _random = new Random(seed);
            _generationParameters = generationParameters;
            _loadedStructure      = DungeonStructureConcretizer.ConcretizeStructure(structure, _random);
            _loadedRooms          = RoomResourceLoader.LoadRoomPrototypes(_loadedStructure);
            _marginHalf           = structure.StructureMetaData.MarginUnit / 2f;
            CollectMetaData(_loadedStructure);

            if (_generationParameters != null)
            {
                ParameterizeDungeon();
            }

            if (_stepBackCounter == null)
            {
                _stepBackCounter = new StepBackCounter(DefaultMaxSteps);
            }
        }
        private void CreateBranches(RoomPrototype firstRoomWrapper)
        {
            var branchDataWrapper = _loadedStructure.NodeMetaData.BranchDataWrapper;

            if (branchDataWrapper == null)
            {
                return;
            }

            var branchPrototypeNames = branchDataWrapper.BranchPrototypeNames;
            var openConnections      = new Stack <RoomPrototypeConnection>(CollectOpenConnections(firstRoomWrapper).Shuffle(_random));

            uint remainingBranchNum;

            if (branchDataWrapper.BranchCount.HasValue)
            {
                remainingBranchNum = branchDataWrapper.BranchCount.Value;
            }
            else if (branchDataWrapper.BranchPercentage.HasValue)
            {
                remainingBranchNum = (uint)(branchDataWrapper.BranchPercentage.Value * openConnections.Count / 100);
            }
            else
            {
                return;
            }

            int extremeCntr      = 100;
            var embeddedDungeons = new ReadOnlyDictionary <string, AbstractDungeonStructure>(_loadedStructure.AbstractStructure.EmbeddedDungeons);

            while (openConnections.Count > 0 && remainingBranchNum > 0 && extremeCntr > 0)
            {
                var connection = openConnections.Pop();
                foreach (var selectedBranchType in branchPrototypeNames.Shuffle(_random))
                {
                    AbstractDungeonStructure embeddedBranchDungeon = _loadedStructure.AbstractStructure.EmbeddedDungeons[selectedBranchType];
                    DungeonNode concretizedDungeonBranch           = DungeonStructureConcretizer.ConcretizeDungeonTree(
                        embeddedBranchDungeon.StartElement,
                        _random,
                        embeddedDungeons);

                    _stepBackCounter.ResetBranch();

                    try
                    {
                        if (GetPossibleRoomsForConnection(connection, concretizedDungeonBranch).Any(BuildPrototypeRoomRecur))
                        {
                            remainingBranchNum--;
                            connection.ParentRoomPrototype.ActualGraphElement.AddSubElement(concretizedDungeonBranch);
                            concretizedDungeonBranch.TraverseDepthFirst().ForEach(n => n.MetaData.AddTag(BRANCH_TAG));
                            break;
                        }
                    }
                    catch (MaxStepsReachedException e)
                    {
                        Debug.LogWarning(e.Message);
                    }
                }

                extremeCntr--;
            }
        }