MPewsey.ManiaMap 2.5.1

dotnet add package MPewsey.ManiaMap --version 2.5.1                
NuGet\Install-Package MPewsey.ManiaMap -Version 2.5.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MPewsey.ManiaMap" Version="2.5.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add MPewsey.ManiaMap --version 2.5.1                
#r "nuget: MPewsey.ManiaMap, 2.5.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install MPewsey.ManiaMap as a Cake Addin
#addin nuget:?package=MPewsey.ManiaMap&version=2.5.1

// Install MPewsey.ManiaMap as a Cake Tool
#tool nuget:?package=MPewsey.ManiaMap&version=2.5.1                

ManiaMap

Tests Docs codecov .NET Standard NuGet

About

This package allows for the creation of procedurally generated metroidvania style layouts from user-defined level layout graphs and room templates. The resulting layouts can be used in games and to render maps, such as that shown below.

BigMap

Features

  • Single and multi-layer 2D room layout generation.
  • Graph-based procedural generation.
  • Specification of room connection constraints by defining door directions and matching door codes.
  • Rendering of generated layouts to image files using built-in or custom map tiles.
  • Procedural distribution of collectables throughout layout.
  • Supports gradual map discovery through cell filters.
  • Persistence of layout and layout state data through JSON and XML via Data Contract serialization.

Game Engine Support

Layout Generator Example

The following subsections outline how to use the LayoutGenerator class to generate a room layout.

Step 1: Create Room Templates

The generator creates rooms by pulling from user-defined room templates. Room templates consist of a 2D array of cells, that may be empty (a null value) or filled. Each cell includes the possible door connections (north, south, east, west, top, and/or bottom) that can be made from that cell to other rooms.

The following code provides an example for the creation of a simple 3x3 square room template. In it, a series of cells are created and have doors set to them via directional characters ("N" = North, "S" = South, etc.). The cells are then assigned to a 2D array to create the geometry of the layout. Finally, these cells are passed to the RoomTemplate initializer, along with a unique ID, to create the room template.

var o = Cell.New;
var a = Cell.New.SetDoors("WN", Door.TwoWay);
var b = Cell.New.SetDoors("N", Door.TwoWay);
var c = Cell.New.SetDoors("NE", Door.TwoWay);
var d = Cell.New.SetDoors("W", Door.TwoWay);
var e = Cell.New.SetDoors("E", Door.TwoWay);
var f = Cell.New.SetDoors("WS", Door.TwoWay);
var g = Cell.New.SetDoors("S", Door.TwoWay);
var h = Cell.New.SetDoors("SE", Door.TwoWay);

var cells = new Cell[,]
{
    { a, b, c },
    { d, o, e },
    { f, g, h },
};

var roomTemplate = new RoomTemplate(id: 1, name: "Square", cells: cells);

Step 2: Assign Room Templates to Template Groups

Once some room template have been defined, they must be added to one or more room template groups, which can be referenced by name later. This is accomplished by simply adding them to a TemplateGroups object:

var templateGroups = new TemplateGroups();
templateGroups.Add("Default", roomTemplate);

Step 3: Create a Layout Graph

To provide a designed feel to generated layouts, the generator uses a room layout graph as the basis for generating layouts. The layout graph consists of nodes, representing rooms, and edges, representing door connections between rooms.

Each graph element can be assigned one or more room template groups (created in Step 2) from which room templates can be drawn for that location. Z (layer) values can also be assigned to elements to create a multi-level room layout.

In the below example, the graph shown in the image is created by adding edges to a graph. In the process, the connecting nodes are automatically created. Afterwards, the code loops over all created nodes and assigns the "Default" template group name to them.

var graph = new LayoutGraph(id: 1, name: "ExampleGraph");

// Define edges between nodes. Nodes not already in graph will automatically be created.
graph.AddEdge(0, 1);
graph.AddEdge(1, 2);
graph.AddEdge(0, 3);
graph.AddEdge(0, 4);
graph.AddEdge(0, 5);

// Add "Default" template group to nodes.
foreach (var node in graph.GetNodes())
{
    node.TemplateGroup = "Default";
}

Example Layout Graph

Step 4: Run the Layout Generator

To create repeatable layouts, a random seed is used by the layout generator. To generate a room layout, simply select a seed and pass your layout graph and room template groups to the LayoutGenerator, as shown below. In the example, a map of the layout is also rendered and saved using the LayoutMap class. For this instance, the default built-in tiles are used. However, custom tiles can also be specified by the user.

var layoutId = 1;
var seed = new RandomSeed(12345);
var generator = new LayoutGenerator();
var layout = generator.Generate(layoutId, graph, templateGroups, seed);

// Render map and save it to file
var map = new LayoutMap();
map.SaveImage("Map.png", layout);

Map

Collectable Generator Example

The collectable generator distributes collectables throughout a layout.

var seed = new RandomSeed(12345);
var generator = new CollectableGenerator();

// Add collectable ID's to groups. Multiple ID's may be added for the same item.
// These groups will also need to be assigned to some room template cells.
var collectableGroups = new CollectableGroups();
collectableGroups.Add("Group1", new int[] { 1, 1, 1, 2, 3, 4, 5 });
collectableGroups.Add("Group2", new int[] { 6, 7, 7, 8, 8, 9, 10 });

generator.Generate(layout, collectableGroups, seed);

Layout Graph Selector Example

The layout graph selector draws a random layout graph from a supplied list. This is useful when used as an early step in a Pipeline.

// Create a list of graphs from which to draw.
var graphs = new List<LayoutGraph>
{
    new LayoutGraph(id: 1, name: "ExampleGraph1"),
    new LayoutGraph(id: 2, name: "ExampleGraph2"),
    new LayoutGraph(id: 3, name: "ExampleGraph3"),
};

var seed = new RandomSeed(12345);
var selector = new LayoutGraphSelector();
var graph = selector.DrawSelection(graphs, seed);

Layout Graph Randomizer Example

The layout graph randomizer generates variations of a layout graph based on user-defined swappable nodes.

var seed = new RandomSeed(12345);
var graph = new LayoutGraph(id: 1, name: "ExampleGraph");

// Add any nodes and edges to the graph.
// See the previous Layout Generator example.

// Add nodes to variation groups.
// The nodes in these groups will be shuffled and swapped by the randomizer.
graph.AddNodeVariation("Group1", new int[] { 1, 5, 3 });
graph.AddNodeVariation("Group2", new int[] { 0, 7, 10, 12 });

// Create a randomizer and create a new graph variation.
var randomizer = new LayoutGraphRandomizer();
var graphVariation = randomizer.RandomizeGraph(graph, seed);

Generation Pipeline Example

The generation pipeline provides a way for multiple generation steps to be chained together. This is often easier than making manual calls to each generation step.

// Create a dictionary of inputs to be passed to each pipeline step.
var inputs = new Dictionary<string, object>
{
    { "LayoutId", 1 },
    { "LayoutGraph", graph },
    { "TemplateGroups", templateGroups },
    { "CollectableGroups", collectableGroups },
    { "RandomSeed", seed },
};

// Use the default pipeline
var pipeline = PipelineBuilder.CreateDefaultPipeline();

// Or create your own
pipeline = new Pipeline(new LayoutGenerator(), new CollectableGenerator());

var results = pipeline.Run(inputs);
var layout = results.GetOutput<Layout>("Layout");
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.5.1 128 7/23/2024
2.5.0 157 5/13/2024
2.4.0 244 11/5/2023
2.3.0 392 10/17/2022
2.2.0 408 9/27/2022
2.1.0 391 9/9/2022
2.0.3 396 9/3/2022
2.0.2 374 8/27/2022
2.0.1 390 8/11/2022
2.0.0 414 6/29/2022
1.5.0 425 5/30/2022
1.4.1 410 5/30/2022
1.4.0 409 5/29/2022
1.3.0 413 5/26/2022
1.2.0 441 4/19/2022
1.1.0 421 4/15/2022
1.0.0 416 4/3/2022