The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

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/.