NAME
Game::TextMapper::Folkesten - generate fantasy wilderness maps
SYNOPSIS
my $text = Game::TextMapper::Folkesten->new
->generate_map();
DESCRIPTION
This generates a wilderness map based on the algorithm by Andreas Folkesten. See the blog posts at http://arch-brick.blogspot.com/2023/08/hexmap-terrain-generator.html.
METHODS
Note that this module acts as a class with the generate_map
method, but none of the other subroutines defined are actual methods. They don't take a $self
argument.
neighbors
The list of directions for neighbours one step away (0 to 5).
random_neighbor
A random direction for a neighbour one step away (a random integer from 0 to 5).
neighbor($hex, $i)
say join(",", $map->neighbor("0203", 1));
# 2,2
Returns the coordinates of a neighbor in a particular direction (0 to 5), one step away.
$hex
is an array reference of coordinates or a string that can be turned into one using the xy
method.
$i
is a direction (0 to 5).
xy($coordinates)
$coordinates
is a string with four digites and interpreted as coordinates and returned, e.g. returns (2, 3) for "0203".
legal($x, $y) or $legal($coordinates)
say "legal" if $map->legal(10,10);
Turn $coordinates into ($x, $y), assuming each to be two digits, i.e. "0203" turns into (2, 3).
Return ($x, $y) if the coordinates are legal, i.e. on the map.
neighbors($hex)
say join(" ", $map->neighbors("0203"));
# 0202 0303 0304 0204 0104 0103 0102
Returns the list of legal neighbours, one step away. This could be just two neighbours (e.g. around 0101).
$hex
is an array reference of coordinates or a string that can be turned into one using the xy
method.
generate_plains
All hexes are plains.
generate_ocean
1d6-2 edges of the map are ocean. Randomly determine which ones. Every hex on these edges is ocean. Every hex bordering an ocean hex has a 50% chance to be ocean. Every hex bordering one of these secondary ocean hexes has a 33% chance to be ocean, unless it has already been rolled for.
generate_mountains
Place 1d6 mountain hexes. Roll two d10s for each to determine its coordinates. If you end up in an ocean hex or a previous mountain hex, roll again. Every plains hex adjacent to a mountain hex has a 4 in 6 chance to be mountains as well; otherwise, it is hills. Repeat, but now with a 2 in 6 chance. Every plains hex adjacent to a hill hex has a 3 in 6 chance to be hills.
rivers
The original instructions are: "Roll 1d6 to determine how many major rivers there are: 1 none, 2-4 one, 5 two, 6 two rivers joining into one. Each river has a 3 in 6 chance to be flowing out of a mountain or hill hex; otherwise, it enters from the edge of the map (if there is a land edge). If there is an ocean on the map, the rivers will flow into it."
Instead of doing that, let's try this: "A river starts in ever mountain and every hill, flowing downwards if possible: from mountains to hills, from hills to plains and from plains into the ocean or off the map. Pick the lowest lying neighbour. We can mark these as canyons, later. When a river meets another river, then merge them (same tail) or subsume them (if meerging with the beginning of an existing river)."
generate_canyons
Check all the rivers: if it flows "uphill", add a canyon
generate_dry
The wind blows from west or east. Follow the wind in straight horizontal lines. Once the line hits a mountain, all the following hexes are dry hills or dry plains except if it has a river.
generate_forest
Every hex with a river has a 50% chance to be forested. Every hills or plains hex without a river that isn’t dry or next to a dry hex has a 1 in 6 chance to be forested; 2 in 6 if it is next to a forested river hex.
generate_swamp
A 1 in 6 chance on every plain river hex that isn't next to a dry hex.
generate_islands
Every ocean hex has a 1 in 6 chance of having an island.
string
Create the string output.
generate_map
Start with a 10 by 10 hexmap.
SEE ALSO
Andreas Folkesten described this algorithm in the following blog post: http://arch-brick.blogspot.com/2023/08/hexmap-terrain-generator.html.
The map itself uses the Light icons by Alex Schroeder. These are dedicated to the public domain. See http://creativecommons.org/licenses/by-sa/3.0/.