Skip to content

Programmatically Modify the DungeonFlow

It's possible to modify the DungeonFlow or any other DunGen asset at runtime to manipulate how the dungeon is generated.

Permanent Changes

Care must be taken when modifying any DunGen asset that derives from ScriptableObject (e.g., TileSet, Archetype, DungeonFlow, etc). Modifying these assets will make permanent changes to your project. You will need to copy the asset first (using Instantiate(originalAsset)) and work only on the duplicate asset to avoid permanent change to your project. You'll also need to consider deep copies if, for example, you'd like to change one of the Tiles inside a TileSet that belongs to your DungeonFlow.

Here's an example of how you could duplicate a DungeonFlow and swap the Tiles that appear on the Goal node with one or more boss Tiles. Useful for if you'd like a boss to appear only on certain floors, but otherwise want the DungeonFlow to be identical to your regular floors, and don't want to have to maintain multiple near-identical Dungeon Flows.

SwapGoalNode.cs
using DunGen;
using DunGen.Graph;
using System.Linq;
using UnityEngine;

public class SwapGoalNode : MonoBehaviour
{
    /// <summary>
    /// The original dungeon flow asset we want to swap the goal of
    /// </summary>
    public DungeonFlow OriginalFlow;
    /// <summary>
    /// The replacement boss room tiles to use as the goal
    /// </summary>
    public TileSet BossRoomTileSet;

    /// <summary>
    /// The duplicated dungeon flow with its goal overridden. We can pass this
    /// to the dungeon generator to generate a copy of our dungeon with the swapped goal node
    /// </summary>
    public DungeonFlow BossRoomFlow { get; private set; }


    private void Start()
    {
        if (OriginalFlow == null)
            return;

        // Make a copy of the original flow
        // IMPORTANT: Be very careful modifying the dungeon flow asset at runtime. Since it's a 
        // ScriptableObject, any changes to the original will affect the settings inside your actual project.
        // This also goes for sub-objects inside the dungeon flow (such as TileSets). Anything derived from a
        // ScriptableObject should be duplicated first before any modifications are applied to avoid making
        // permanent changes to your project
        BossRoomFlow = Instantiate(OriginalFlow);

        // Find the goal node
        var goalNode = BossRoomFlow.Nodes.First(x => x.NodeType == NodeType.Goal);

        // Set the boss room TileSet as the only goal node
        goalNode.TileSets.Clear();
        goalNode.TileSets.Add(BossRoomTileSet);

        // Now we can pass our new BossRoomFlow into the Generator of our RuntimeDungeon component and call Generate()
    }
}