User:NoitaArena/Staging/World generation

From Noita Wiki
Jump to navigation Jump to search

The Biomes are pseudorandomly generated via a combination of "Wang tiles" and "Pixel scenes".

Wang Tiles

Wang tiles are tiles which connect together based edge-based rules. They are very common in texture generation but can also be adapted to generate any sort of repeating pattern, like grass. Specifically, Noita uses corner-based herringbone Wang tiles implemented with stb_serringbone , which has very helpful documentation on the theory of Wang tiles as well as a large list of example rule sets (see hbw_2222 examples).

The general goal is to make a set of tiles that match up together and enough of them to avoid repetition. Each tile has a set of edges and you apply rules to those edges. Rules which you yourself define. To make a non-repetitive layout 2 sub-classes for each edge type is recommend.

E.G. You choose that right of a Red edge is always solid and walk able. The area around Yellow edges is ice.

Now using those rules when you draw the tiles, where ever there is a Red->Yellow edge, you put an ice bridge.

If you had a sub-class for Red's edge type (0 in this case) and made the rule "crumbling pathway" you would put down breaking ice. By using a distinct edge subclass the trap would blend into the generated world more subtly as the surrounding rooms wouldn't give it away.

If you generate a tile set using specific rules from the example rule sets, your network of pathway connections will have distinctive repeating layouts. The drawback being the number of tiles required for a full set with 2 colors per vertex.

Definitions of the 4 vertices wang_gen.exe

// TILE CONSTRAINT TYPES
//
// there are 4 "types" of corners and 6 types of edges.
// you can configure the tileset to have different numbers
// of colors for each type of color or edge.
//
// corner types:
//
//                     0---*---1---*---2---*---3
//                     |       |               |
//                     *       *               *
//                     |       |               |
//     1---*---2---*---3       0---*---1---*---2
//     |               |       |
//     *               *       *
//     |               |       |
//     0---*---1---*---2---*---3
//
//
//  edge types:
//
//     *---2---*---3---*      *---0---*
//     |               |      |       |
//     1               4      5       1
//     |               |      |       |
//     *---0---*---2---*      *       *
//                            |       |
//                            4       5
//                            |       |
//                            *---3---*
//
// TILE CONSTRAINTS
//
// each corner/edge has a color; this shows the name
// of the variable containing the color
//
// corner constraints:
//
//                        a---*---d
//                        |       |
//                        *       *
//                        |       |
//     a---*---b---*---c  b       e
//     |               |  |       |
//     *               *  *       *
//     |               |  |       |
//     d---*---e---*---f  c---*---f
//
//
//  edge constraints:
//
//     *---a---*---b---*      *---a---*
//     |               |      |       |
//     c               d      b       c
//     |               |      |       |
//     *---e---*---f---*      *       *
//                            |       |
//                            d       e
//                            |       |
//                            *---f---*
//


Long vertical paths and dead ends

You can make a blank template using wang_gen.exe, located in the tools_modding folder.

wang_gen.exe {outfile} c {sidelen} {c0} {c1} {c2} {c3} [{vx} {vy}]
     {outfile}  -- filename that template will be written to as PNG
     {sidelen}  -- length of short side of rectangle in pixels
     {c0}       -- number of colors for corner type 0
     {c1}       -- number of colors for corner type 1
     {c2}       -- number of colors for corner type 2
     {c3}       -- number of colors for corner type 3
     {vx}       -- number of color-duplicating variations horizontally in template
     {vy}       -- number of color-duplicating variations vertically in template

You can also use it to see what the existing biome's settings are using the 'i' switch. Conveniently it will also tell you what command to run in order to make a template with the same settings.

wang_gen.exe data\wang_tiles\coalmine.png i
info:
  is_corner: 1
  short_side_len: 13
  num_color[0]: 1
  num_color[1]: 2
  num_color[2]: 1
  num_color[3]: 2
  num_color[4]: 0
  num_color[5]: 0
  num_vary_x: 3
  num_vary_y: 3
wang_gen.exe data\wang_tiles\coalmine.png c 13 1 2 1 2 3 3

The Coal Mines has 13px wide tiles, uses 1, 2, 1, 2 for the colors for each corner type, and then duplicates those templates by 3 times in both x and y.

You could then run that given command to make a new template and, assuming you follow similar edge rules to the original, create a new Coal Mines that is very similar to the original.

Looking at Horscht's awesome web-based wang tiler gives a clear visual explanation.

This example of a single wang tile from the Coal Pits generates the associated structure

Examples of the wang tiles from the Mines (full, and zoomed section) can be seen below.

A catalog of the HP Up Locations has been compiled.

Pixel scenes

Pixel scenes are added to the rendered biome.

Material colors

Material Colors.png

The colors in the wang tiles represent materials, as assigned by data/materials.xml and documented in the image at right.

Wang files store the format data in the 3 top right pixels, everything else can be edited. Making your own palette in the blank template area will not break the tile map.

Loading Process

/data/biome/_biomes_all.xml is loaded.

Biome map is loaded, data/biome_impl/biome_map.png

Each pixel is then processed as according to the biome assigned to it.

E.G. all the ffd57917 pixels are assigned to data/biome/coalmine.xml

Now the game needs to fill that biome area with terrain. Using the Wang tiles it generates a random map and crops it to the biome.

The newly generated layout is then tested. If the game cannot find an path through it a new map is generated. This is repeated numerous times until it is forced to give an unsolvable level. (Note this is only a warning message, not all levels abide by this consistently.)

Purple show reachable area, the line shows the path finder's solution.
Pathfinding Result

Once all the biomes are generated a completed map is stored,

When the player enters a new area this map is read and the pixels are processed into the materials they represent.

Debugging Wang Maps

Magic Numbers

DEBUG_WANG="1" [Default: 0]

Using "DEBUG_WANG_MAPS" the game will export information on world generation into /temptemp/. Disable this and clear temptemp when you are finished!

DEBUG_WANG_PATH="1"  [Default: 0]

Adds the pathfinder solution to the completed wang map as pixel color #FF00FF. You can use this and assign #FF00FF a material/entity to show the pathfinding solution in game. Note that by default the color is not assigned to anything and the pathfinding line will be rendered in using the default biome material. This will look confusing since it will blend into the ground material.

DEBUG_THREADED_WORLD_CREATION="0" [Default: 1]

By default the world it generated using multiple threads. This is an issue when you are debugging and log lines start to overlap and become unreadable. Disabling this makes the world load in using a single thread making your logs consistent.

DEBUG_LUA_LOG_BIOME_SPAWN_SCRIPTS="1" [Default: 0]

Log every script invoked during world building. Consider disabling DEBUG_THREADED_WORLD_CREATION while using this.

DEBUG_LUA_REPORT_BIOME_SPAWN_ERRORS="1"  [Default: 1]

Log all errors reported by biome spawn scripts. Consider disabling DEBUG_THREADED_WORLD_CREATION while using this.

DEBUG_FULL_WANG_MAPS="1" [Default: 0]

Loads in the wang file as a tile map and not a tile set. This makes the game treat your wang file as an already assembled map and will load it in as is instead of building a map out of the tiles in the wang file.

WORLD_SEED="123456789" [Default: 0]

Sets the world seed to a static number. Using this your generated map will always be consistent.

BIOME_MAP="data/biome_impl/biome_map.png" [Default: "data/biome_impl/biome_map.png"]

Override the biome map used. It can be useful to make a new biome map with just a large chunk of the biome you are testing so it generates a large chunk of map for you to test at once.

DESIGN_PLAYER_START_POS_X="227" [Default: 227]
DESIGN_PLAYER_START_POS_Y="-85" [Default: -85]

Set the new game spawn location. Useful to make your character spawn directly at your biome when loading a new game.

Others.

Not specific to world generation but generally useful during debug sessions:

DEBUG_PLAYER_NEVER_DIES="1" [Default: 0]
DEBUG_NO_LOGO_SPLASHES="1"  [Default: 0]
DEBUG_NO_PAUSE_ON_WINDOW_FOCUS_LOST="1"  [Default: 0]

Unknowns.

Other magic numbers seemingly related to world generation, use unknown.

DEBUG_GENERATE_BIG_WANG_MAP="0"
BIOME_USE_BIG_WANG="1"
BIOME_RANDOM_BLOCK_CHANCE="0.5"
BIOME_PATH_FIND_HEIGHT_LIMIT="205"
BIOME_PATH_FIND_WORLD_POS_MAX_X="223"
BIOME_PATH_FIND_WORLD_POS_MIN_X="159"


Debug Mode

Using the Shift-F7 debug menu you can reload wang tiles without having to restart the game. Using this you can tweak individual tiles and reload them without having to restart the game or search for that particular tile in the new world generation. Freezing the AI also helps while doing this so they don't move from their spawning location.



Assembled Wang Maps


See also