ManiaMap.Godot
Procedural generation of metroidvania style maps for Godot .NET.
|
The following subsections outline how to procedurally generate an arrangement of rooms, called a Layout
.
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.
RoomNode2D
or RoomNode3D
depending on whether you wish to develop in 2D or 3D. One of these node types must serve as the root of your room scene.Note: For
RoomNode3D
, you must be in the top view in order to edit cell activities. The top view can be navigated to by clicking the positive Y axis on the axis gizmo or selectingTop View
from the 3D main window's perspective menu. The toolbar will show a check mark when the cells can be edited.
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.
Doors define the locations where two rooms can be connected. At least one door must be added to a room.
DoorNode2D
or DoorNode3D
as a child of the room based on your room type. To save time, you may wish to create your doors as separate scenes with any related nodes, such as sprites or collision, as children. These scenes can then be referenced in your room scene.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 CollectableSpot2D
, Feature2D
, RoomFlag2D
, or their respective 3D nodes can also be added to the room if you wish them to be included.
The procedural generator uses one or more RoomTemplateResource
exported from RoomNode2D
or RoomNode3D
to generate layouts.
Update Room Template
button on the room toolbar. This will create a RoomTemplateResource
with the .room_template.tres
extension at the same path as the scene.Project > Tools > Mania Map > Batch Update Room Templates
option from the menu.One or more TemplateGroup
are used by the procedural generator to determine which rooms can be assigned to a given position in a layout.
Create New... > Resource
, then create a new TemplateGroup
.Entries
property, add a new TemplateGroupEntry
element and assign a RoomTemplateResource
to the Room Template
property slot. Repeat this for all rooms that you wish to assign to the group.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.
Create New... > Resource
, then create a new LayoutGraphResource
.Graph Editor
tab will appear in Godot's bottom panel.Graph Editor
panel, right click to add nodes, which will serve as room locations, to the graph.TemplateGroup
assigned; though it is optional for edges.Note: Edits to the layout graph will be saved automatically when Godot or the graph editor panel are closed.
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 plugin, the output is most notably a room Layout
.
GenerationPipeline
node to a new or existing scene.Add Default Nodes
in the inspector. This will create a pipeline capable of generating a Layout
.LayoutGraphResource
to the automatically generated LayoutGraphsInput
node.CollectableGroup
to the automatically generated CollectableGroupsInput
node.GenerationPipeline
you wish to run, and call the Run
, RunAsync
, or RunAttemptsAsync
methods to generate a layout. For example: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
RunAttempsAsync
method can help by automatically falling back to other seeds.