10 DunGenExtender
Raphtalia edited this page 2024-11-04 17:19:56 +00:00

Important Features

Dungeon Flow

The DungeonFlow that the DunGenExtender asset will influence. Each DungeonFlow can have only one DunGenExtender.

Main Path

MainPathCount is the amount of main paths that the dungeon try to generate. If set to 1, then the dungeon generation will default to the vanilla behaviour of, well, generating only one main path and its branching paths. If set to 2, then the dungeon generation will try to create one additional main path from the first MainRoomTilePrefab tile in the base main path. It will then create the branching paths for each main path.

Static Gif

If the generation fails to fully create any of the main paths for any reason, it will reset the entire dungeon generation and try again. The length of these additional main paths is the same as the base main path, and its starting node for length calculation purposes is at the base main path's starting node.

MainRoomTilePrefab cannot be null. If set to null, the dungeon generation failsafes to the default vanilla generation behaviour. MainRoomTilePrefab can be located practically anywhere on the main path, but it must spawn at least once. It is highly advised that MainRoomTilePrefab has multiple doorways at different directions/elevations/distances etc.

MainRoomTilePrefab can be used in conjunction with the MainRoomDoorwayGroups component for more control in which doorways that the alternate main paths choose. See here for details.

NOTE: Adding an additional main path is effectively adding an entirely separate dungeon to your interior. This is due to the fact that it not only adds a set amount of main tiles, but also branching paths with their tiles. It is highly recommended to decrease the length of the dungeon as you increase MainPathCount.

The DungeonFlow's node list is replicated onto the alternate main paths. The starting index is based on the MainPathCopyNodeBehaviour selected. Any nodes before the starting index will be ignored and not be generated. Injection tiles will not duplicated.

Copy From Main Path Position

The starting index is the first node whose position is greater than the MainRoomTilePrefab's depth on the first main path. In other words, all nodes whose depth is higher than the MainRoomTilePrefab's depth will be replicated.

Copy From Node List

The starting index is the first node whose tilesets contain MainRoomTilePrefab plus 1. By using this behaviour, we are depending on the nodes section to spawn the MainRoomTilePrefab tile instead of the vanilla method with the unique door socket. The node section MUST contain some node whose tileset contains MainRoomTilePrefab.

Main Path Details

A list of MainPathExtender assets that override some of DungeonFlow's values depending on the main path generation order. You can use this feature to create more unique dungeon generations for each main path (i.e. some main paths are shorten/longer than others).

When the first main path is being generated (DungeonFlow's default main path), it will try and get the first item in the list. It will then use those values (if any exist) over DungeonFlow's values for that main path. When the second main path is being generated (the first alternate main path), it will try and get the second item in the list and do the same. It will repeat this pattern for all main paths. If the list or item is empty, no value is overridden. If it tries to get an item outside of the list's range (i.e. when the third main path is being generated and the list only contains two items), then it will grab the last item in the list instead.

You can override the following values of DungeonFlow:

  • Branch Mode
  • Branch Count
  • Length
  • Nodes
  • Lines

⚠️ WARNING: ⚠️ If you are using the CopyFromNodeList behaviour and you are overriding the nodes list, then that list MUST still contain some node whose tileset contains MainRoomTilePrefab.

Archetypes on Normal Nodes

Enable this feature by toggling AddArchetypesToNormalNodes. This allows normal nodes in DungeonFlow to create branching paths by attaching an archetype to it.

Each element of the NormalNodeArchetypes list represents which node receives an archetype. The Label describes which normal node of the same Label will receive one of the archetypes in the Archetypes list. If the Label is empty or white-spaced, then it becomes the default target for any normal node who did not have a corresponding Label in the NormalNodeArchetypes list. If a normal node does not have any corresponding target, then it's spawned tile will not create branching paths like normal.

NOTE: Start and End nodes cannot receive archetypes.



Nice to Have Features

Dungeon Bounds

Enable this feature by toggling UseDungeonBounds. This adds a bounds to your interior where the dungeon generation cannot place tiles outside of. This can help preventing the dungeon from creating paths all the way to Narnia.

NOTE: This feature also increases the chance of the dungeon generation failing, and therefore increasing dungeon generation times. This can even make dungeon generation impossible if the bounds is too small or mispositioned.

DungeonSizeBase is the base size of the bounds. This influences how DungeonSizeFactor work. Otherwise it's self-explanatory.

DungeonSizeFactor is how much the base size of the bounds increases as the dungeon's size increases. If any axis is set to 1, then the base size of that axis will be multiplied by the dungeon's size. If set to 0.5, then the base size is only multiplied by half of the dungeon's size. If set to 0, then the base size is a constant and is uninfluenced by the dungeon's size.

DungeonPositionOffset is the positional offset applied to the bounds.

DungeonPositionPivot is the pivot of the bounds.

The following text is the script that calculates the Bounds:

Bounds GetDungeonBounds(float dungeonScale) {
  var size = DungeonSizeBase + Vector3.Scale(DungeonSizeBase * (dungeonScale - 1), DungeonSizeFactor);
  var offset = DungeonPositionOffset + Vector3.Scale(size, DungeonPositionPivot - Vector3.one * 0.5f);
  return new Bounds(offset, size);
}

Additional Tiles (renamed from Forced Tiles)

Enable this feature by toggling UseAdditionalTiles. This attempts to generate additional branch tiles after the main and branch paths are generated. Each element in the AdditionalTileSets list will attempt to generate one tile from its Tilesets. Where the tile will generate can be influenced with MainPathWeight, BranchPathWeight, and DepthWeightScale, the same as DunGen's Tileset.

The dungeon generation will attempt to generate the tile on every main and branch tile (excluding tiles generated from the Additional Tiles feature). This feature does not guarantee that that tile will generate. If the tile cannot generate for whatever reason, it will simply proceed as normal.

NOTE: This feature may be replicated with injection rules however they are a few key differences.

Injection rules replace main or branch tiles with one of its own tiles when the main and branch paths are being generated. Additional Tiles adds extra tiles after the main and branch paths are generated.

If Injection rules uses a dead-end tile with only one doorway, then the main or branch path will prematurely end (this can cause the dungeon generation to reset). If Additional Tiles uses the same tile, the main or branch path's generation will not be affected.

If Injection rules uses a tile with many doorways on the main path, then those doorways can be used to create branch paths. If Additional Tiles uses the same tile, those doorways will not be used to create branch paths.

Branch Path Multi Simulation

Enable this feature by toggling UseBranchPathMultiSim. This causes the dungeon generation to simulate multiple paths for each branch path. It then assigns each path with a weight based on the weights described below. The simulated path with the highest weight will then be chosen and generated. This feature slows dungeon generation a bit, though it only happens after the main paths are generated (where most of the dungeon generation time is spent).

SimulationCount is the number of simulated paths per branch path. Increasing this value can increase the chance of finding your desired path, but will increase Branch Path Times and vice versa. Please understand that increasing the chance doesn't guarantee that the perfect path can be found.

Length Weight

These weight scales prioritize long branch paths.

LengthWeightScale is the weight scale for the branch path's length. The length of the branch path is multiplied by the scale and is added to the branch path's weight. Increasing this value will prioritize very long branch paths.

NormalizedLengthWeightScale is the weight scale for the branch path's normalized length. The normalized length (0 -> 1) of the branch path (PathLength / MaxPathLength) is multiplied by the scale and is added to the branch path's weight. Increasing this value will prioritize branch paths who meet their maximum path length.

Same Path Connections Weight

These weight scales prioritize branch paths that connect back to their own main path.

SamePathBaseWeightScale is the weight scale for the branch path's number of connections to the same main path. The number of possible connections is multiplied by the scale and is added to the branch path's weight. Increasing this value will prioritize branch paths who make path loops in their main path in general.

SamePathDepthWeightScale is the weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight. Increasing this value will prioritize branch paths who make deep path loops to their main paths.

SamePathNormalizedDepthWeightScale is the weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight. Increasing this value will prioritize branch paths who make generally deep path loops to their main paths.

Different Path Connections Weight

These weight scales prioritize branch paths that connect back to other main paths.

DiffPathBaseWeightScale is the weight scale for the branch path's number of connections to other main paths. The number of possible connections is multiplied by the scale and is added to the branch path's weight. Increasing this value will prioritize branch paths who make path loops in their main path in general.

DiffPathDepthWeightScale is the weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight. Increasing this value will prioritize branch paths who make deep path loops to their other main paths.

DiffPathNormalizedDepthWeightScale is the weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight. Increasing this value will prioritize branch paths who make generally deep path loops to other main paths.

NOTE: This feature can encourages the dungeon generation to generate circular/looping paths. However if your interior does not create looping paths naturally by sheer chance, this feature will have very little to no effect.

Max Shadows Request

Enable this feature by toggling UseMaxShadowsRequestUpdate. This prevents the Max shadow requests count reached warning spam that can appear if the interior has too many lights in close proximity. MaxShadowsRequestAmount will become the new amount of shadow requests.

NOTE: By default, Lethal Company uses 4 shadow requests. I find from my experience that 8-16 shadow requests is more than enough to stop the warning spam.



Niche Features

Doorway Sisters

Enable this feature by toggling UseDoorwaySisters. This feature requires the usage of the DoorwaySisters component to do anything. This prevents an intersecting doorway from generating into an actual doorway IF it's sister doorway has already generated AND both of these doorways lead to the intersecting, neighbor tile. See here for that component's details.

When the dungeon is generating, two tiles may generate right next to each other and one of each of their doorways may be intersecting at the same position. This is an intersecting doorway. The dungeon generation will then roll to see if it will generate the intersecting doorway as an actual doorway. However there is a possibility that when that doorway spawns, it will have a locked door and a neighboring, already generated, doorway will have an open door. If both doorways were to lead to the same tile, then it will defeat the whole purpose of the locked door. This is the scenario that this feature was designed for.

This features adds the slightest bit of slowdown to the dungeon generation times, whether or not the DoorwaySisters component is used. As such, if you don't plan to use this feature, it is advised to disable this feature.

NOTE: This feature is probably not necessary for your interior. My interior was designed to pack my tiles very closely and for their doorways to have a high chance of intersecting. As such, my interior developed the issue of having too many unnecessary doorways and required this feature to fix it. Most interiors won't have this same issue.

Line Randomizer

Enable this feature by toggling UseLineRandomizer. This helps dungeons with the combination of a large amount of tiles and/or large amount of doorways for each tile to generate a bit faster while maintaining some of the dungeon generation randomness.

When the dungeon is generating and trying to add a new tile, it will try and insert every possible tile and each of its doorways to the previous tile's doorway. As the amount of tiles increases and the amount of doorways per tiles increases, this number of possible doorway pairs can very quickly gets out of hand. This can drastically increase dungeon generation times if not addressed. This is the scenario that this feature was designed for.

This feature modifies the list of archetypes in LineRandomizerArchetypes to receive a random set of tilesets from LineRandomizerTileSets. This insures that the archetype will have less overall tiles to progress, and therefore less possible doorway pairs to calculate. Furthermore, since the tilesets received are random the dungeon generation continues to be random, though admittedly less overall.

LineRandomizerArchetypes is the archetypes whose list of tilesets will be modified. Ideally these archetypes will be used in the lines section of DungeonFlow. The last LineRandomizerTakeCount amount of elements of both the archetype's TileSets and BranchCapTileSets list will be exchanged by a random set of tilesets from LineRandomizerTileSets. As such, the length of those lists must be equal or greater than the value of LineRandomizerTakeCount. This goes without saying but be prepared the archetypes' elements to be swapped around all willynilly-ing.

NOTE: This feature is probably not necessary for your interior. My interior was reaching up to 2000 potential doorway pairs for each tile injection and needed a way to reduce it. And even with this fix, the doorway pairs bubble sort rewrite was probably the bigger performance boost anyway. Still, I needed a way to future-proof my dungeon generation times and such this feature still exists.