Skip to content

Commit

Permalink
Update README and layout generation instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
mpewsey committed Jun 14, 2024
1 parent c676239 commit 3a0cbd4
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 85 deletions.
6 changes: 3 additions & 3 deletions Docs/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -874,9 +874,9 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.

INPUT = ../Packages/ManiaMap.Unity/Scripts \
../Scripts \
../README.md
INPUT = ../Packages/ManiaMap.Unity/Scripts/Runtime \
../README.md \
pages/layout-generation-instructions.md

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
Expand Down
97 changes: 97 additions & 0 deletions Docs/pages/layout-generation-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Generating a Layout

The following subsections outline how to procedurally generate an arrangement of rooms, called a `Layout`.

## Step 1: Create Rooms and Room Templates

The procedural generator creates layouts by pulling from user-defined room templates. To the generator, a room is a collection of cells in a grid, with information, such as the available door connections, assigned to them.

### Creating a Room

1. In the Unity scene heirarchy, right-click then select `Mania Map > Room`.
2. In the inspector, specify the room's type, whether you intend to work with 2D or 3D physics.
3. Specify the number of cell rows and columns, along with the cell size to create the bounding shape of the room.
4. When the room node is selected, a toolbar will appear in the Godot main window (Circled in red in the screenshot below). The options on this toolbar may be used to edit the cell activities to further define the shape of the room. For instance, selecting the toggle edit mode button, then clicking or dragging over cells in the view will toggle the targeted cells on or off.
5. Save the room as a prefab.

In the below screenshot, the cells for an angle shaped room have been created, with the active cells shown in blue and inactive cells shown in red and crossed-out. The active cells are the regions where we intend to build our scene.

![Screenshot 2024-06-14 182659](https://github.com/mpewsey/ManiaMap.Unity/assets/23442063/f4248cb5-54f0-4db3-8b66-955a54efe5b6)

### Creating Doors

Doors define the locations where two rooms can be connected. At least one door must be added to a room.

1. Right-click on the room in the scene heirarchy and select `Mania Map > Door`. To save time, you may wish to save your doors as prefabs with any related components, such as sprites or collision. These prefabs can then be referenced in your room prefab.
2. Position the door within the room and assign its direction and connection constraints.
4. To auto assign the closest cell and direction to the door, make sure the applicable flags are selected in the inspector and click the `Auto Assign` button on the room toolbar. The assigned door direction will be based on its location relative to the center of its assigned cell.

Additional room child nodes such as `CollectableSpotComponent`, `Feature`, and `RoomFlag` can also be added to the room if you wish them to be included.

The below screenshot shows a square 3x3 room with doors around its entire perimeter. Each of the door direction (north, west, east, and south) use a different prefab since the tiles depicting the doors are different for each.

![Screenshot 2024-06-14 184508](https://github.com/mpewsey/ManiaMap.Unity/assets/23442063/7cd8e3dc-7723-4d7d-bfbf-37eb6d1b210e)

### Exporting Room Templates

The procedural generator uses one or more `RoomTemplateResource` exported from a room to generate layouts.

1. With at least one room saved as a prefab in your project, from the top toolbar, select `Mania Map > Batch Update Room Templates`.
2. This operation will perform auto assignment on all room prefabs throughout the project and save `RoomTemplateResource` Scriptable Objects with the `.room_template.asset` extension to the prefab paths.

## Step 2: Create Room Template Groups

One or more `TemplateGroup` are used by the procedural generator to determine which rooms can be assigned to a given position in a layout.

1. To create a template group, right-click in the Unity project explorer and select `Create > Mania Map > Template Group`.
2. Click on the newly created template group and, in the inspector, assign a unique name to the group.
3. Drag and drop one or more `RoomTemplateResource` into the rectangular region to add them to the group.

> **Note:** Locking the inspector and searching `t:RoomTemplateResource` in the project explorer can make adding room templates to a group easier.
## Step 3: Create a Layout Graph

The procedural generator uses a `LayoutGraphResource` as a base for generating layouts. This allows you to design high level relationships between rooms while still making the resulting layout appear random.

1. To create a layout graph, right-click in the Unity project explorer and select `Create > Mania Map > Layout Graph`.
2. Double click on the created object to open the graph editor window.
3. In the graph editor window, right click in an open area, then select `Create Node` to add a node to the graph. Each node will serve as a room location.
4. To add edges, serving as connections between rooms, to the graph, right-click on the starting node and select `Add Edge`, then click on a second node to make the connection.
5. Selecting nodes and/or edges will allow you to edit their properties in the inspector. Each node must have a `TemplateGroup` assigned; though it is optional of edges.

![Screenshot 2024-06-14 191811](https://github.com/mpewsey/ManiaMap.Unity/assets/23442063/b3b44803-7173-4a48-af0b-05d034b6b2e7)

## Step 4: Create a Generation Pipeline

The `GenerationPipeline` takes various inputs and feeds them through a series of operational steps to generate one or more outputs. In the context of this package, the output is most notably a room `Layout`.

1. To create a pipeline, right-click in the scene heirarchy and select `Mania Map > Generation Pipeline`. A pipeline with the default inputs and steps will be created.
2. On the `Inputs` Game Object, add one or more `LayoutGraphResource` to the `LayoutGraphsInput` component.
3. Optionally, add one or more `CollectableGroup` to the `CollectableGroupsInput` component.
4. Create a script that references the `GenerationPipeline` you wish to run, and call the `Run`, `RunAsync`, or `RunAttemptsAsync` methods to generate a layout. For example:

```ExampleGenerationPipelineRunner.cs
using MPewsey.ManiaMap;
using MPewsey.ManiaMapGodot.Generators;

public class ExampleGenerationPipelineRunner : MonoBehaviour
{
[SerializeField] public GenerationPipeline _pipeline;

public void RunPipeline()
{
var results = _pipeline.Run();
var layout = results.GetOutput<Layout>("Layout");

// At this point, you will probably want to do something with the layout...
//
// * You could save it to file using the JsonSerialization or XmlSerialization static classes.
// * You could use a RoomDatabase or RoomTemplateGroupDatabase to instantiate the rooms in the layout.
// * You could use it with the LayoutTileMap or LayoutTileMapBook components to generate maps.
//
// See the project samples for example implementations.
}
}
```

> **Note:** Depending on your room templates and layout graph, it may not be possible to generate a layout for all (if any) random seeds. If you are encountering issues with successfully generating a layout, you may need to reconsider the constraints imposed on its generation. For example, you may need to add more doors to ensure that your rooms have a better chance of connecting. Even then, you may still encounter some isolated failures, in which case the generation pipeline `RunAttemptsAsync` method can help by automatically falling back to other seeds.
88 changes: 6 additions & 82 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
![Unity ≥ 2022.1](https://img.shields.io/badge/Unity-%E2%89%A5%202022.1-blue)
![Version](https://img.shields.io/github/v/tag/mpewsey/ManiaMap.Unity?label=Version)

> [!Important]
> Due to a major recent refactor, the README and documentation are out of date. There are plans to update them in the coming dates.
## About

This package provides components for interfacing the [ManiaMap](https://github.com/mpewsey/ManiaMap) procedural layout generator with Unity.
Expand All @@ -31,6 +28,11 @@ To lock into a specific version, append `#{VERSION_TAG}` to the end of the URL.
https://github.com/mpewsey/ManiaMap.Unity.git?path=Packages/ManiaMap.Unity#v0.0.3
```

## Documentation

For information on the scripting API, as well as instructions related to procedurally generating a room layout, see the [documentation](https://mpewsey.github.io/ManiaMap.Unity/md_pages_layout_generation_instructions.html).


## Samples

Sample scenes are available in the project `Assets` directory. To explore them, clone this repository and open the project in Unity.
Expand Down Expand Up @@ -64,82 +66,4 @@ Sample scenes are available in the project `Assets` directory. To explore them,
<td width='50%' align='center'>
</td>
</tr>
</table>

## Example

The following subsections outline how to procedurally generate a layout.

### Step 1: Create Room Templates

The generator creates rooms by pulling from user-defined rooms. To the generator a room is essentially a collection of cells in a grid, with information, such as door connections, assigned to them.

#### Creating a Room

1. Create a new `Room` by selecting `GameObject > Mania Map > Room`. Create a prefab for this Game Object that may be utilized later.
2. In the inspector, provide a name for the room, along with its width and height in terms of cells.
3. Click the `Update Room` button to generate the cells.

![Generated Cells](https://user-images.githubusercontent.com/23442063/175812812-5871bc8c-84e0-4b2f-ae04-0073c9aaed61.png)

4. In the scene view, select any empty cells and set the `Is Empty` flag in the inspector. The cell Gizmos will show crossed out for empty cells.

![Empty Cells](https://user-images.githubusercontent.com/23442063/175812984-1e05c096-9a93-4855-9b34-fb566083ddcc.png)

5. Next, add all possible doors and collectable spots to the room per the following sections.

#### Creating Doors

1. Create a new `Door` by selecting the Room Game Object then `GameObject > Mania Map > Door`. The door should be added as a child of the room.
2. At this point, you should probably create a prefab for the door with art supporting the particular direction, along with all applicable events. However, those specifics are beyond the scope of this example.
3. Position the door at the desired location within the room and assign its direction and connection constraints.
4. To auto assign the closest cell and direction to the door, make sure the applicable flags are selected and click the `Auto Assign` button. Note that the `Update Room` button on the Room component will also perform this operation on all doors in the room.

![Doors](https://user-images.githubusercontent.com/23442063/175813945-080a6eab-f333-4036-8816-90a2746401d7.png)

#### Creating Collectable Spots

1. Create a new `CollectableSpot` by selecting the Room Game Object then `GameObject > Mania Map > Collectable Spot`. The collectable spot should be added as a child of the room.
2. At this point, you should probably create a prefab for the collectable spot with art (treasure chest, orb, sparkle, etc.) and all applicable events. However, those specifics are beyond the scope of this example.
3. Position the collectable spot at the desired location within the room and assign a collectable group to it (`Assets > Mania Map > CollectableGroup`).
4. To auto assign the closest cell to the collectable spot, make sure the applicable flag is selected and click the `Auto Assign` button. Note that the `Update Room` button on the Room component will also perform this operation on all collectable spots in the room.

![Collectable Spot](https://user-images.githubusercontent.com/23442063/175827419-9639dd11-18ad-4c99-97b0-571984efab97.png)

#### Saving Room Templates

1. Ensure that any rooms are saved as prefabs within the project. Next, select `Mania Map > Batch Save Templates` from the menu to save room templates for all room prefabs discovered within the project. Note that the settings for this action may be configured in the settings at `Resources/ManiaMap/TemplateSaveSettings` once the action has been run once.

### Step 2: Create Room Template Groups

1. Create a `TemplateGroup` by selecting `Assets > Mania Map > Template Group`.
2. In the inspector, provide a unique name to the group and add any of the generated room templates you wish to associate with the group to the list.

![Template Group](https://user-images.githubusercontent.com/23442063/175827410-a61dcbc4-2275-4217-bd83-4fff0f048e5d.png)

### Step 3: Create Layout Graphs

1. Create a `LayoutGraph` by selecting `Assets > Mania Map > Layout Graph`.
2. Double click on the asset to open the graph editor.
3. Add rooms (nodes) to the graph by right-clicking in the graph area and selecting `Add Node`.
4. In the inspector, add a template group to the selected nodes to associate the room templates that may be used at those locations.
5. Add edges to the graph by right-clicking a node, selecting `Add Edge`, then selecting another node.
6. To edit the edge attributes, ensure that `View > Toggle Edge Display` is enabled, then select the edges in the graph area.

![Layout Graph](https://user-images.githubusercontent.com/23442063/175828288-b47a1e3d-ac81-4a2a-b436-0f22b7da3a6c.png)

### Step 4: Create Generation Pipeline

1. Create a `GenerationPipeline` by selecting `GameObject > Mania Map > Generation Pipeline`.
2. Select the child `<Inputs>` Game Object and add any layout graphs and collectable groups you wish to associate with the generator to the inputs.

![Generation Pipeline](https://user-images.githubusercontent.com/23442063/175828818-3a0a09da-69d8-4d60-a48c-b69d4ceac374.png)

3. To run the pipeline and generate a layout, run the `Run` method from a script.

```Generate.cs
var results = Pipeline.Run();

// Retrieve the generated layout data from the ouput results
var layout = results.GetOutput<Layout>("Layout");
```
</table>

0 comments on commit 3a0cbd4

Please sign in to comment.