Skip to content
warp edited this page Dec 15, 2025 · 13 revisions

This page is a work in progress

Overview

A valheim Dungeon consists of two main parts:

  1. An exterior location
  2. An interior collection of procedurally placed rooms.

Dungeon Exterior

The dungeon exterior is similar to all other locations. It is placed during world generation and will follow location placement rules. However, it should have an attached DungeonGenerator to generate the dungeon rooms as well as a teleport to transfer the player from exterior to interior.

  • It's a good idea to set the exterior BiomeArea to Median. This ensures the resulting DG transform will likely be placed inside the zone.

Dungeon Interior

A dungeon interior is a collection of procedurally placed rooms. A DungeonGenerator holds a Theme field and will attempt to place rooms with the same Theme. Each individual room has one, or many, room connection's. For each room connection, the DungeonGenerator will attempt to place another room given a set of room connection parameters. Dungeon generation will stop when the max rooms is met or when a room exceeds the bounds of it's starting zone.

  • If using m_useCustomInteriorTransform, then also set the transform.position.z value of DungeonGenerator prefab to -30.
  • Endcaps should have at least one Room.Size value equal to 0.
  • Endcaps should use a transform.rotation of 0,0,0

Building Rooms in UnityEditor

There are a few quirks to building dungeon rooms in Valheim.

  1. Room sizes should be configured so as to not allow rooms to exceed the bounds of their starting zone. If a room exceeds the bounds of it's starting zone and therefore places a room connection outside the starting zone, that room connection will not receive another room. This can be circumvented by ensuring all rooms fit neatly into a 64x64 size zone or by creating endcaps with a room size of 0.

  2. The transform rotation values on room connections must follow a specific pattern. See attached image below. With the UnityEditor compass in the same orientation as shown. North facing room connections must use the rotation values on the top of the black square. South facing room connections must use the rotation values on the bottom of the black square. Etc...

Valheim Dungeon Room Connection Transform Values

  1. Room connection prefab transform.position values should be integers. The room connection prefab should be placed at the edge of room. For example, if a room is 8x8x8 and has a transform.position of 0,0,0 then the local position of a room connection prefab should be 8,0,0.

Interior Environment and Zone Boundaries

When an interior environment is assigned via Location.m_interiorEnvironment, the environment is applied at high Y-values within the same zone as the exterior location. If the dungeon interior crosses into an adjacent zone, the environment will stop applying, often appearing as a hard black wall aligned with the zone boundary.

This commonly occurs when the exterior location is placed near the edge of a zone and the dungeon interior extends beyond the original 64x64 area.

This can be visualized using mods such as ZoneScouter, which can display zone boundaries in the sky. The environment cutoff will align exactly with a zone edge.

Solution 1: Use a Custom Interior Transform (Recommended)

Enable the following fields on both prefabs:

  • DungeonGenerator.m_useCustomInteriorTransform
  • Location.m_useCustomInteriorTransform

This forces the dungeon interior to spawn at a deterministic position within the zone, avoiding zone crossover.

When enabled, place the dungeon interior at a fixed offset, commonly:

  • transform.position = (0, -32, 0)

Since zones are 64x64, this positions the dungeon safely within the zone instead of relying on exterior placement randomness.

Important constraints:

  • The entrance room must be oriented so it builds into the zone, not outward. Ensure RoomConnection transforms are correctly rotated.
  • All rooms must fit entirely within a single 64x64 zone.
  • Room Size values should be divisible by 4 to prevent cumulative overflow.
    • Example: eight 8x8 rooms fit exactly (64m).
    • Mixing incompatible sizes (e.g. 8x8 + 10x10) can push placement outside the zone.

Solution 2: Per-Room Interior Environments (Limited)

An interior environment can be applied to a prefab inside the dungeon instead of using Location.m_interiorEnvironment.

This is useful for large or special rooms (e.g. oversized boss rooms) where placement cannot be controlled.

This approach is fragile:

  • Only the room containing the environment is guaranteed to render correctly.
  • Other rooms may still cross zone boundaries and lose the environment.

Debugging

  • Many issues arise from incorrect transform.rotation values.

Tips

  • Utilize the vanilla RandomPieceRotation script to rotate pieces like vines for a more natural look.

Clone this wiki locally