Post Processing

This plugin series lets algorithms generate a skeleton first and then provides a set of functions to beautify it step-by-step to get a whole map. This so-called post-processing is independent of the chosen algorithm – in other words: you can use all the features described below in combination with every map generation algorithm!

Each function tries to imitate a map designer’s work step when mapping. These steps are:

  • Walls, elevated floor, …
  • Shadings (e.g. darker grass, dirt, …)
  • Bioms (e.g. desert, snowland, ashes on a Worldmap)
  • Large objects or assets
  • Details (e.g. plants, flowers, small rocks, …)
  • Events

All actions can be done in any order, even multiple times or omitted. We go through all of them and explain how to combine them to create a fancy map.

Structures (Walls)

Using the Structures feature, you can define rules that scan for specific areas and replace them with pre-defined tiles. The most prominent example here is to look for places where a ceiling tile meets a floor tile and to draw a wall in here.

Let’s create a new map, call it „Structures“ (or any other name) with the same tileset you selected in the Space Map and put it below.

Now, let’s look at this screenshot:

This map defines, on its left, combinations of tiles, that the generator will scan for. Any area from the generated map that fits one matcher is replaced by any combination from its right. We’ll go into more detail now. Each row consists of

  • one Region Id block (blue), that assigns this row with a width&height and a number. The number does not matter, so just start from 1 and count up.
  • at least one Matcher (orange), each matcher must have the same width&height than your region Id block. Use blank tiles as joker.
  • one blank area with the same size than your region Id block, to separate matchers from replacements. If your matchers have a width of e.g. 2 each, then the blank area must be 2 tiles wide, too.
  • at least one Replacement (green); draw what should be drawn by the generator. For instance, walls, assets, dirts… You can set a Region Id Stopper 61 to make blank objects.

Examples

For a dungeon with 2 tile-high walls, I found out this layout works quite good.

Multiple Maps

You can have multiple maps to define Structures. E.g., you can have a map called „Structures“ for the walls and another map called „Details“ for details.

  • You can freely choose the names of the maps

JavaScript Calls

Extend your Script Call to something like this:

...
.generate()
.drawStructures()
.drawStructures("Details")
.finalize();

The line „drawStructures“ must contain the map’s name in which you defined the structures. If it is „Structures,“ you can leave it out.

Tips and Ideas

  • You can have multiple maps to define Structures to organize your setup. I usually have a map called „Structures“ and a map called „Details“.
  • The generator works from top to bottom. That means, you can use the upper rows to define basic structures, walls, etc. and then you can set a wall as matcher itself to define more details.
  • For the replacements, you can draw the same element multiple times, to get a ratio.
  • You can use the Region Id Stopper 61. For example, draw 4 different flowers, leave 20 tiles empty, and then draw a Region 61 Stopper. Then you get a 1:5 ratio that a flower is drawn.
  • Having a wall and a water tile below will create a waterfall! (Everytime or by chance, as you define it)
  • Wall tiles that are right next to water tiles will have a higher change of having greens.

Having a 61 Stopper Tile, the generator will now include all assets being on its left, regardless of whether they are blank or not. As a blank tile won’t modify the result, you can use this technique to draw assets by probability. Looking at this screenshot above, there’s a roughly 1:3 change of an object being placed.

Last but not least, you can build an elevated floor too!

Details

The „Details“ feature works similarly to the Structures feature with one exception: Impassable assets are not drawn on areas that need to be passable according to the chosen algorithm. Every map generation algorithm defines „reserved“ spaces automatically. Use this feature to add details or assets while not afraid of blocking your player.

JavaScript Calls

Extend your Script Call to something like this:

...
.generate()
.drawStructures()
.drawDetails()
.drawDetails("Flowers")
.finalize();

The line „drawDetails“ must contain the map’s name in which you defined the structures. If it is „Details,“ it can be left out.

Decoration and Assets

The term assets would fit better, but this article keeps the term decoration for historical reasons.

A Decoration Map works basically the same as the Structures Map, but it has some special rules. While tiles on the Structures Map are drawn consistently, decorations are not added automatically. Decorations are added x-times instead, and therefore they are usually used to spawn loot chests or monsters.

To create a Decoration Map, create a new Map, call it „Decoration“ (exactly this name), again use the same tileset, and put it below the Space Map. Place Assets as we did before in the Structure’s Map.

Don’t use reserved Region Ids, that are 5, 6, 13, and 61 by default.

Example having loot chests and monsters

JavaScript Calls

There are multiple commands that you can choose from. Those commands are available:

  • drawDecoration
  • drawDecorationXTimes (that is identical to the one above)
  • drawChest
  • drawLootChest (that is identical to the one above)
  • drawEnemy
  • drawPOI
  • drawSwitch

Depending on the current implementation of this plugin series, some commands work identical, but it makes it easier for me to expand features in the future.

Examples:

...
.drawDecoration(1, 3, 5)
.drawChest(11, 2, 4)
.drawEnemy(14, 2, 3)
.drawPOI(15)
.drawSwitch(16)
.finalize();

As you can see, you can call those methods multiple times and in any order. Sometimes it’s easier to draw Loot chests before the Details.

Every function in this section works as follows:

.drawDecoration(11)

will draw any asset from region Id 11 exactly once – if possible.

.drawDecoration(11, 3)

will draw any asset from region Id 11 exactly 3 times – if possible.

.drawDecoration(11, 2, 4)

will draw any asset from region Id 11 at least 2 times and 4 times at most – if possible.

„If possible“ refers to the fact that an asset won’t be placed if no places are left on the generated map that matches the decoration’s matchers. In such cases, nothing will happen.

Shadings

Shadings are usually used to draw darker grass, dirt, or any other tile to gain more variety on the map.

Create a Map with any Name (I recommend calling it „Shadings“) and put it below the Space Map.

A Shadings Map consists of one or multiple lines containing these blocks:

  • At least one Matcher
  • one blank Tile
  • one Tile that will be the replacement of the Tiles on the left

You can draw multiple lines to set up Rules for different biomes, e.g., grass becomes darker grass, rock floor becomes dirt, etc. However, having more than one replacement in one line is not supported. I had the experience that most of my Maps only contained one matcher and one substitute.

Multiple Maps

You can have multiple Maps to organize your setup.

JavaScript Calls

...
.drawShadings()
.drawShadings({ mapName: "Dirt", scale: 5 })
...

The curly brackets are the JavaScript annotation to define optional parameters, i.e., „mapName“ and „scale“ are optional and can be skipped.

Biomes

The Map setup to draw Biomes is slightly different from the configuration of the Shadings and Paths. It accepts only one line but outputs multiple Tiles. A Worldmap can accept all kinds of grass and replace it with desert, snowfield, mountains, etc.

  • one line
  • one or multiple matchers on the left
  • one or multiple replacement on the right

Tip: You can also use the biomes feature given a (custom) tileset with various grass types.

JavaScript Calls

...
.drawBiomes()
.drawBiomes({ mapName: "Biomes", scale: 20 })
...

The curly brackets are the JavaScript annotation to define optional parameters, i.e., „mapName“ and „scale“ are optional and can be skipped.

Putting everything together

You can put Structures, Shadings, … in any order, even multiple times or left out. Especially when using many commands, it can become a real puzzle for you. I will add some more articles on setting up my dungeons, and you can always look into the Sample project.

I found out that this order works quite well:

  1. draw the walls
  2. draw points of interest e.g. loot chests, monsters
  3. draw shadings
  4. draw details

MZ only: Plugin Commands

Put Plugin Commands in this order:

  1. Generate Map by using any Algorithm
  2. With Exits
  3. Spawn Player at
  4. Generate
  5. Commands starting with „draw“, in any order
  6. Finalize

MV & MZ: JavaScript Call

A JS Code would look like this.

const args = { }

$mapGenerator.custom("cave", args)
.withExit("top")
.withExit("bottom")
.spawnPlayerAt("bottom")
.generate()
.drawStructures()
...
.finalize()