The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Game::HexDescribe::Utils - utilities to use the Hex Describe data

DESCRIPTION

Hex::Describe is a web application which uses recursive random tables to create the description of a map. This package contains the functions used to access the information outside the web application framework.

list_tables($dir)

This function returns the table names in $dir. These are based on the following filename convention: "$dir/hex-describe-$name-table.txt".

load_table($name, $dir)

This function returns the unparsed table from the filename "$dir/hex-describe-$name-table.txt".

load_map($name, $dir)

This function returns the unparsed map from the filename "$dir/hex-describe-$name-map.txt".

parse_table

This parses the random tables. This is also where *bold* gets translated to HTML. We also do some very basic checking of references. If we refer to another table in square brackets we check whether we've seen such a table.

Table data is a reference to a hash of hashes. The key to the first hash is the name of the table; the key to the second hash is "total" for the number of options and "lines" for a reference to a list of hashes with two keys, "count" (the weight of this lines) and "text" (the text of this line).

A table like the following:

    ;tab
    1,a
    2,b

Would be:

    $table_data->{tab}->{total} == 3
    $table_data->{tab}->{lines}->[0]->{count} == 1
    $table_data->{tab}->{lines}->[0]->{text} eq "a"
    $table_data->{tab}->{lines}->[1]->{count} == 2
    $table_data->{tab}->{lines}->[1]->{text} eq "b"
init

When starting a description, we need to initialize our data. There are two global data structures beyond the map.

$extra is a reference to a hash of lists of hashes used to keep common data per line. In this context, lines are linear structures like rivers or trails on the map. The first hash uses the hex coordinates as a key. This gets you the list of hashes, one per line going through this hex. Each of these hashes uses the key "type" to indicate the type of line, "line" for the raw data (for debugging), and later "name" will be used to name these lines.

    $extra->{"0101"}->[0]->{"type"} eq "river"

%names is just a hash of names. It is used for all sorts of things. When using the reference name for a bugbear band1, then "name for a bugbear band1" will be a key in this hash. When using the reference name for forest foo, then "name for forest foo: 0101" and will be set for every hex sharing that name.

    $names{"name for a bugbear band1"} eq "Long Fangs"
    $names{"name for forest foo: 0101"} eq "Dark Wood"

Note that for /describe/text, init is called for every paragraph.

%locals is a hash of all the "normal" table lookups encountered so far. It is is reset for every paragraph. To refer to a previous result, start a reference with the word "same". This doesn't work for references to adjacent hexes, dice rolls, or names. Here's an example:

    ;village boss
    1,[man] is the village boss. They call him Big [same man].
    1,[woman] is the village boss. They call her Big [same woman].

Thus:

    $locals{man} eq "Alex"

%globals is a hash of hashes of all the table lookups beginning with the word "here" per hex. In a second phase, all the references starting with the word "nearby" will be resolved using these. Here's an example:

    ;ingredient
    1,fey moss
    1,blue worms
    ;forest
    3,There is nothing here but trees.
    1,You find [here ingredient].
    ;village
    1,The alchemist needs [nearby ingredient].

Some of the forest hexes will have one of the two possible ingredients and the village alchemist will want one of the nearby ingredients. Currently, there is a limitation in place: we can only resolve the references starting with the word "nearby" when everything else is done. This means that at that point, references starting with the word "same" will no longer work since %locals will no longer be set.

Thus:

    $globals->{ingredient}->{"0101"} eq "fey moss"
parse_map_data

This does basic parsing of hexes on the map as produced by Text Mapper, for example:

    0101 dark-green trees village
parse_map_lines

This does basic parsing of linear structures on the map as produced by Text Mapper, for example:

     0302-0101 trail

We use compute_missing_points to find all the missing points on the line.

process_map_merge_lines

As we process lines, we want to do two things: if a hex is part of a linear structure, we want to add the type to the terrain features. Thus, given the following hex and river, we want to add "river" to the terrain features of 0101:

    0801-0802-0703-0602-0503-0402-0302-0201-0101-0100 river

The (virtual) result:

    0101 dark-green trees village river

Furthermore, given another river like the following, we want to merge these where they meet (at 0302):

    0701-0601-0501-0401-0302-0201-0101-0100 river

Again, the (virtual) result:

    0302 dark-green trees town river river-merge

If you look at the default map, here are some interesting situations:

A river starts at 0906 but it immediately merges with the river starting at 1005 thus it should be dropped entirely.

A trail starts at 0206 and passes through 0305 on the way to 0404 but it shouldn't end at 0305 just because there's also a trail starting at 0305 going north to 0302.

process_map_start_lines

As we process lines, we also want to note the start of lines: sources of rivers, the beginning of trails. Thus, given the following hex and river, we want to add "river-start" to the terrain features of 0801:

    0801-0802-0703-0602-0503-0402-0302-0201-0101-0100 river

Adds a river to the hex:

    0801 light-grey mountain river river-start

But note that we don't want to do this where linear structures have merged. If a trail ends at a town and merges with other trails there, it doesn't "start" there. It can only be said to start somewhere if no other linear structure starts there.

In case we're not talking about trails and rivers but things like routes from A to B, it might be important to note the fact. Therefore, both ends of the line get a "river-end" (if a river).

parse_map

This calls all the map parsing and processing functions we just talked about.

pick_description

Pick a description from a given table. In the example above, pick a random number between 1 and 3 and then go through the list, addin up counts until you hit that number.

If the result picked is unique, remove it from the list. That is, set it's count to 0 such that it won't ever get picked again.

resolve_redirect

This handles the special redirect syntax: request an URL and if the response code is a 301 or 302, take the location header in the response and return it.

If the environment variable HEX_DESCRIBE_OFFLINE is set, these do not get resolved and the empty string is returned.

pick

This function picks the appropriate table given a particular word (usually a map feature such as "forest" or "river").

This is where context is implemented. Let's start with this hex:

    0101 dark-green trees village river trail

Remember that parsing the map added more terrain than was noted on the map itself. Our function will get called for each of these words, Let's assume it will get called for "dark-green". Before checking whether a table called "dark-green" exists, we want to check whether any of the other words provide enough context to pick a more specific table. Thus, we will check "trees dark-green", "village dark-green", "river dark-green" and "trail dark-green" before checking for "dark-green".

If such a table exists in $table_data, we call pick_description to pick a text from the table and then we go through the text and call describe to resolve any table references in square brackets.

Remember that rules for the remaining words are still being called. Thus, if you write a table for "trees dark-green" (which is going to be picked in preference to "dark-green"), then there should be no table for "trees" because that's the next word that's going to be processed!

describe

This is where all the references get resolved. We handle references to dice rolls, the normal recursive table lookup, and all the special rules for names that get saved once they have been determined both globally or per terrain features. Please refer to the tutorial on the help page for the various features.

describe_text

This function does what describe does, but for simple text without hex coordinates.

normalize_elvish

We do some post-processing of words, inspired by these two web pages, but using our own replacements. http://sindarinlessons.weebly.com/37---how-to-make-names-1.html http://sindarinlessons.weebly.com/38---how-to-make-names-2.html

process

We do some post-processing after the description has been assembled: we move all the IMG tags in a SPAN element with class "images". This makes it easier to lay out the result using CSS.

resolve_appends

This removes text marked for appending and adds it at the end of a hex description. This modifies the third parameter, $descriptions.

resolve_nearby

We have nearly everything resolved except for references starting with the word "nearby" because these require all of the other data to be present. This modifies the third parameter, $descriptions.

closest

This picks the closest instance of whatever we're looking for, but not from the same coordinates, obviously.

distance

Returns the distance between two hexes. Either provide two coordinates (strings in the form "0101", "0102") or four numbers (1, 1, 1, 2).

resolve_other

This is a second phase. We have nearly everything resolved except for references starting with the word "other" because these require all of the other data to be present. This modifies the third parameter, $descriptions.

some_other

This picks some other instance of whatever we're looking for, irrespective of distance.

resolve_later

This is a second phase. We have nearly everything resolved except for references starting with the word "later" because these require all of the other data to be present. This modifies the third parameter, $descriptions. Use this for recursive lookup involving "nearby" and "other".

This also takes care of hex references introduced by "nearby" and "other". This is also why we need to take extra care to call quotemeta on various strings we want to search and replace: these hex references contain parenthesis!

describe_map

This is one of the top entry points: it simply calls describe for every hex in $map_data and calls process on the result. All the texts are collected into a new hash where the hex coordinates are the key and the generated description is the value.

add_labels

This function is used after generating the descriptions to add the new names of rivers and trails to the existing map.

get_label

This function returns the name of a line.

xy

This is a helper function to turn "0101" into ("01", "01") which is equivalent to (1, 1).

coordinates

This is a helper function to turn (1, 1) back into "0101".

neighbour

This is a helper function that takes the coordinates of a hex, a reference like [1,1] or regular coordinates like "0101", and a direction from 0 to 5, and returns the coordinates of the neighbouring hex in that direction.

neighbours

This is a helper function that takes map_data and the coordinates of a hex, a reference like [1,1] or regular coordinates like "0101", and returns a list of existing neighbours, or the string "[…]". This makes a difference at the edge of the map.

one

This is a helper function that picks a random element from a list. This works both for actual lists and for references to lists.

one_step_to

Given a hex to start from, check all directions and figure out which neighbour is closer to your destination. Return the coordinates of this neighbour.

compute_missing_points

Return a list of coordinates in string form. Thus, given a list like ("0302", "0101") it will return ("0302", "0201", "0101").

same_direction

Given two linear structures and a point of contact, return 1 if the these objects go in the same direction on way or the other.

spread_name

This function is used to spread a name along terrain features.

markdown

This allows us to generate Markdown output.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 51:

'=item' outside of any '=over'

=over without closing =back