Guide
Templates and Generation
A DungeonTemplate describes the shape of a dungeon as a tree of rooms: an entrance, the rooms along the way, and an exit. A DungeonManager in your scene turns that tree into a layout made from your room prefabs.
On this page
- How a template works
- Create a template
- What the validator checks
- Generation modes
- DungeonManager settings
- Mode and template
- Expansion (TemplateSequencedRandom)
- Placement and output
- Room pool
- Runtime
- Seed and retries
- Decoration and logging
- Seeds and repeatable layouts
- Wall mode for double-sided kits
- Generation status and events
- Progression requirements
- Common mistakes
How a template works#
- A template is a tree of nodes (room slots or milestones) and edges (connections between them).
- The root node is the Entrance. A template must have exactly one Entrance node.
- Each node has one parent. The validator rejects loops and nodes that cannot be reached from the root.
- An Exit node is normally a leaf. When a template has Exit leaves, the main path ends there.
- Progression requirements can gate the main path only. Branch edges cannot have one.
| Node type | Use |
|---|---|
Entrance | The root. Exactly one per template. |
Normal | A room in the middle of the dungeon. |
Exit | The end of the main path. |
Treasure, Boss | Special rooms, chosen by room type. |
Create a template#
-
Open . Click New, or Load Asset to edit an existing template. To create an empty asset in the Project window, use .
-
Add nodes with Add Node. Select a node and set its fields in Node Details: Node ID, Type (the room type), Prefab (an optional pinned room), and Debug Color.
-
Connect nodes by dragging from one node's port to another. Use Arrange Tree to lay the graph out, and Frame All or Frame Sel to find nodes.
-
Click Validate. Every problem is listed in the Node Details panel. Fix them and validate again.
A template with an Entrance node and no room for it yet. Validation fails until a room is pinned or added to the pool. -
Click Save Asset.
Generate Preview builds the template in the scene so you can check the result. Clear Preview removes it.
What the validator checks#
The validator runs before generation. It reports:
- missing, duplicate, or unresolved node and edge IDs, and a root that does not match the Entrance;
- a tree that is not connected, or a node with more than one parent;
- a room for each node: a pinned prefab, or a pool prefab with the matching Room Type;
- enough doors on each room for its connections;
- progression requirements that cannot be reached, or that have no room to provide them.
Typical messages are no pinnedPrefab and no pool entries and no eligible prefab with RoomType Boss.
Generation modes#
Set the mode on the DungeonManager with Generation Mode.
TemplateExactdefault- Each template node becomes exactly one room, and each edge becomes one connection. The layout is the authored structure. With Add Random Branches In Exact on, the manager also adds random branches to that skeleton.
TemplateSequencedRandom- Template nodes are milestones. The manager inserts seeded filler rooms on each edge, and can add random branches that use spare doorways. Use it when the authored pacing should stay, but the layout should vary between runs.
DungeonManager settings#
The Inspector groups the settings into sections. The defaults are listed below.
Mode and template#
templateDungeonTemplate required- The template to generate. Generation stops with an error when it is empty.
useBurstPlannerbool default off- Uses the Burst-compiled planner. See Burst planner.
addRandomBranchesInExactbool default off- Adds random branches to a TemplateExact layout.
maxSearchNodesint default 10000, minimum 100- Placement attempts before the planner gives up. Raise it for large templates.
allowRotationbool default on- Lets rooms rotate in 90° steps to match socket directions.
Expansion (TemplateSequencedRandom)#
mainPathRoomCountint default 10, minimum 1- Rooms along the main path. It must be at least the number of nodes on the longest main path.
minOffshootSequenceFillers,maxOffshootSequenceFillersint default 0 and 2- Range of filler rooms inserted on each edge off the main path.
maxRandomBranchRoomsint default 10- Room budget for random branches. 0 turns random branches off.
minRandomBranchStarts,maxRandomBranchStartsint default 1 and 1- How many separate branch roots to start. A seeded value is picked in this range.
allowRandomSubbranchesbool default on- Lets branch rooms grow their own branches.
maxRandomBranchDepthint default 4, minimum 1- Longest chain of random branch rooms from a branch root.
Placement and output#
seamPaddingfloat default 0- Space kept between adjacent rooms. Keep it at 0 when walls are shared.
allowedSeamOverlapfloat default 0, minimum 0- How far connected rooms may overlap at a seam. Used to line up shared walls; see Wall mode.
wallModeSeamMode default SingleOnly- How walls are shared at a seam. See Wall mode.
rootTransform default this transform- Parent for the generated rooms.
sceneEntranceRoomData optional- A room you placed in the scene by hand. The dungeon grows from it.
useEntranceSeamPadding,entranceSeamPaddingbool, float default off and 0- Override
seamPaddingfor the rooms attached directly to the scene entrance.
Room pool#
The Room Pool is the list of candidate rooms for nodes without a pinned prefab. Drag prefabs onto the drop zone; each one is added with weight 1 and all contexts. Each entry has:
prefabGameObject- A room prefab with
RoomDataandDoorSocketchildren. weightfloat minimum 0- Relative chance of being picked. A weight of 0 turns random picking off. A pinned node still uses its prefab.
allowedContextsRoomPlacementContext All when empty- Where the room may be picked:
Template(a template node),SequenceFiller(a filler on an edge), orRandomBranch. Set boss and treasure rooms toTemplateso they only appear at their nodes.
Runtime#
spawnPrototypePlayer,prototypePlayerPrefabbool, GameObject default on, empty- Spawns a player prefab at the entrance after generation.
generationFramesint default 1, minimum 1- Spreads generation over this many frames in Play Mode. 1 runs in one frame.
generationFrameBudgetMsfloat default 0- Millisecond budget per frame for placing rooms and decoration in Play Mode. 0 turns the budget off.
roomPoolPrewarm,decorationPoolPrewarmint default 5 and 20- Copies of each room and decoration prefab created in advance. 0 creates them on demand.
prewarmOnAwakebool default on- Measures the prefabs and fills the pool in
Awake, so the first generation is faster.
Seed and retries#
useRandomSeedbool default on- Draws a new seed for each run. Turn it off to use
seed. seedint default 0- The seed used when
useRandomSeedis off. maxPlanRetriesint default 50- Extra planning attempts with a new seed when rooms do not fit.
planRetryTimeoutMsint default 2000- Time limit for all retries. 0 means no time limit.
Decoration and logging#
decorateAfterGenerationbool default on- Decorates each room that has a
RoomDecorationAuthoringafter generation. Turn it off while you debug the layout. logGeneration,logDecorationDiagnosticsbool default off- Extra log output for the generation run and for decoration.
Seeds and repeatable layouts#
With Use Random Seed on, each run gets a new seed. Turn it off and set Seed to get the same layout every time. Use a fixed seed while you test, and random seeds for play.
The planner may retry with a derived seed when rooms do not fit. The requested seed still reproduces the same result. The Burst planner is deterministic too, but it is a separate implementation, so the same seed can give a different valid layout than the managed planner.
Wall mode for double-sided kits#
Each room prefab carries its own walls and one door per doorway. When two rooms connect, two walls meet at the seam. Wall Mode decides what happens there.
SingleOnlydefault- Every room keeps its own walls. Use it for one-sided kits, where the back of each wall is open. A doorway then shows the theme's door variant, which plugs the hole in the partner wall.
DoubleOnly- Rooms must be double-sided. Each connection shares one wall and one door. The validator rejects any pinned or pool prefab that is not double-sided.
AllowBoth- Shares walls where both rooms are double-sided and keeps both walls everywhere else.
- In the Dungeon Theme Wizard, Grid card, turn on Double-Sided Walls for the theme. Leave the door variant prefab empty, because a double-sided kit does not need a plug.
- Save the room prefabs again, or rebuild them all with the Room Prefab Manager. The room then gets
supportsDoubleWalls. - Set Wall Mode to
DoubleOnlyorAllowBoth. - Tune Allowed Seam Overlap. Start at 0 and increase it until the room's floor meets the wall at the seam. For the Gridness demo kit the value is 0.71.
At each shared seam, one room (the keeper) keeps its wall and its door. The other room's doorway becomes a bare passage. A positive net gap (seamPadding minus allowedSeamOverlap) leaves the two walls apart, so keep Seam Padding at 0 when you share walls.
Double-Sided Ceilings is a separate option. The floor slab of the storey above then serves as the ceiling, so the theme's ceiling prefab list must be empty.
Generation status and events#
A run is always in one of five states, reported by the read-only Status property:
| Status | Meaning |
|---|---|
Idle | No run has started. |
Generating | A run is in progress. IsGenerating is true, and GenerationProgress goes from 0 to 1. |
Ready | The run finished, including decoration and post-processing. |
Failed | The run failed. The dungeon from the last successful run stays in the scene. |
Cancelled | The run was cancelled. |
StatusChanged is raised with the new status each time it changes.
using DungeonGen;
using UnityEngine;
public class DungeonLoader : MonoBehaviour
{
[SerializeField] private DungeonManager dungeon;
private void Start()
{
dungeon.StatusChanged += status => Debug.Log($"Dungeon status: {status}");
dungeon.Generate();
}
}
A call to Generate() made while a run is still in progress is ignored with a warning.
Progression requirements#
A progression requirement gates a connection on the main path until the player has the item that unlocks it. It is built from three pieces:
- Progression Requirement asset (): a
StableId(set it so the ID survives a rename; it falls back to the asset name when empty), a display name, and the default item prefab. - Gated edge: an edge in the template with a requirement. Set it on the
DungeonTemplateasset in the Inspector, in its Edges list. The Template Designer window has no requirement field in version 1.1.0. - Provider node: a node that provides the item. Add the requirement to its Provided Requirements list in the template asset.
Room prefabs need the matching components:
- the door on the gated connection needs a connection gate, such as
BasicConnectionGate; - the room that provides the item needs an
ItemSpawnPoint, which places the item prefab there.
The validator checks that a provider exists before each gate and that the Exit can still be reached. A missing provider is reported as has no reachable provider before the gate.
Common mistakes#
- Generation does nothing. Check the template is assigned and the Console for validation errors. See Troubleshooting.
- A node has no room. Pin a prefab, or add a pool prefab with the same Room Type.
- Walls double up at every seam. The kit is double-sided but Wall Mode is
SingleOnly. See Wall mode.