How it works
This page gives an overview of the node_map.lua script including the basics of its operation and the function calls necessary to use it.
Topics
 How it works
Step 1: Find all Nodes on Current Map
The script looks for all map entities with the prefix "node_" and stores them in a table. Then it makes connections between nodes with distances that are less than or equal to 13 tiles (208 pixels) apart.
node_map:scan_all_nodes()
Note: This step is performed automatically each time you load a map.
Step 2: Mapping the Nodes to a Specified Location
Next you tell it where you want to go by specifying a pair of map coordinates in pixels.
local mapping = node_map:new_mapping(dst_x, dst_y, dst_layer)
It then calculates the cumulative distance from every node to those coordinates. So if the first node is 8 tiles away, and the second node is 10 tiles from the first, then the second node is considered 18 tiles away from the destination. Maybe there's an alternate route where the second node is 9 tiles away from a third node, and that node is only 7 tiles away from the destination coordinates. In that case, once it checks that alternate route, it will change the cumulative distance for node 2 from 18 to 16 tiles. Then eventually it will have found the shortest cumulative distance for every node to those coordinates, and it stores that data in an internal table.
A more detailed description of the algorithm used can be found here.
A mapping object will be returned that retains the distance calculations associated with these destination coordinates. This mapping object is only useful for finding a route to these specific coordinates. If you later need to go somewhere else, then generate a new mapping object for those coordinates.
The mapping object will no longer be useful once you switch maps and thus should be discarded.
Step 3: Find the Best Node Leading to the Destination from Your Current Location
The last step is to tell it where you currently are, and it returns the coordinates of the optimal node that you should move to on a route leading to the destination. It also returns the total route distance that this node is away from the final destination.
local x, y, distance, action = mapping:next_node(x, y, layer)
To determine that node, it first finds all nodes within 13 tiles of your current location. Then among those, it simply returns whichever one has the lowest cumulative distance to the destination.
This is an iterative processes, so once you reach the node it specified, you would call the function again, this time giving your new position. Then a new node is returned which is closer to the destination than the current node. You continue this process until you eventually reach the destination.
In order to find the next node, your current location and the destination both have to be within range of nodes connected to the same node network.
Note: If you have multiple map entities that you want to move to the same destination coordinates using the node network, then you can share the same mapping object for both.
If you have map entities that you want to move to different coordinates, then you will need to generate separate mapping objects for each entity.
Extra Features
Find entire route upfront
If you want to get the full route to the destination instead of getting one segment of the journey each time, then you can instead call:
local route = mapping:find_route(x_start, y_start, layer_start)
This will find the entire route starting at map coordinates x_start & y_start and ending at the destination coordinates the mapping object was set to.
It returns a table array with an entry corresponding to each segment of the full route. Each entry is a key/value table with the following keys and values:
 x (number, integer)  x coordinate in pixels for the starting location for this segment
 y (number, integer)  y coordinate in pixels for the starting location for this segment
 distance (number, nonnegative)  the total distance remaining from the start coordinates to the final destination
 action (string or nil)  describes any special movement involved in this segment, where possible values are:

nil
 regular segment 
"teletransporter"
 moving from a teletransporter node to another teletransporter node, for which the distance of this segment may be longer than normally allowed

The first table entry will contain the starting coordinates and the distance of the entire route. The last table entry will contain the destination coordinates with a distance of 0.
If you want to get the full route and you have no other use for the corresponding mapping object, then a more convenient way to get the same result is to use the following instead:
local route = node_map:find_route(x_start, y_start, layer_start, x_end, y_end, layer_end)
This is equivalent to doing the following:
local mapping = self:new_mapping(x_end, y_end, layer_end)
local route = mapping:find_route(x_start, y_start, layer_start)
Get the total route distance from a node to the final destination
If you want to see how far a specific node is from the final destination coordinates (number in pixels), you can use the following:
mapping:get_distance(node)
Where the mapping object has be set for the desired destination and node
is a map entity for one of the nodes.
If the specified node is not connected to the same node network as the destination, then it returns nil.
Iterate through nodes in the same network
To iterate through all the nodes connected to the same node network as the destination coordinates of the mapping object, use the following:
for i,node in mapping:iter_nodes() do
add your code here
end
Here i
(number, integer, positive) is the index of the node, and node
is the map entity for the node. The order of the iteration is starting with the node that has the lowest total route distance to the destination and in ascending order to the farthest one.
If you only want to know the number of nodes in the network then you can simply use:
mapping:get_node_count()
Special Node Types
Stairs Nodes
Nodes are normally only connected to other nodes that are both in range and on the same layer. Stairs nodes, however, can span multiple layers and are connected to other nodes in range that are on any of those layers.
To designate a node to behave as stairs, add the custom property "layers"
and for its value list all the layers that it should be connected to, using commas or spaces (or both) to separate each one (e.g. "1, 2, 3"
).
When a stairs node is used to change layers, the layer variable returned by node_map:next_node()
will be a number giving the new layer to transition to (when the entity being moved is at the stairs node).
Teletransporter Nodes
Teletransporter nodes provide a way to instantly travel between two nodes regardless of which layer they are on or the distance apart. A teletransporter node is connected to every other teletransporter node on the map.
To designate a node to behave as a teletransporter, add the custom property "node_type"
with a value of "teletransporter"
.
When traveling between two teletransporter nodes, node_map:next_node()
will return an action variable with a value of "teletransporter"
indicating that the travel to the next node should be instant.