Skip to content

Connections and neighbours

Nodes on a campaign map are joined by connections. A filter can ask about them in two different ways, and the difference is the thing to get right:

  • has a connection tests the connection itself: its type, its text or its tags.
  • connected to tests the node at the far end of a connection, which is the neighbour.

Both conditions sit in a group like any other, so you can mix them with the conditions from the Conditions and Groups pages. Choose how you would like to see the examples; the Guide remembers your choice.

Has a connection, or connected to

“Has a connection” looks at the connections a node has, and the node matches when one of them passes the test. Here the test is that the connection’s type is “Sails from”:

Has a connection: the ships and the ports they sail from

The five ships each have a “Sails from” connection, and so do the two ports they sail from, Varrow and Grey Harbour. All seven stay on the map. In an expression the function is connection(…), and the condition inside it can use only type, text and tags, because a connection has nothing else.

Builder The builder view of Include connection(type = "Sails from")
Expression
Include
connection(type = "Sails from")

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connection(type = "Sails from").
After After: Include connection(type = "Sails from"). Shows 7 of 32 nodes.
Shows 7 of 32 nodes

“Connected to” looks through the connection at the node on the other side. The node matches when a neighbour passes the test. Here the test is that the neighbour is a ship:

Connected to: the nodes beside a ship

Now the ships themselves have gone, unless another ship is next to them. What stays is everything with a ship as a neighbour: Port Varrow and Grey Harbour, the cove where the Gannet calls, Corra, who captains the Last Lantern, and the two clues that point at ships. In an expression the function is connected_to(…), and the condition inside it can use everything a node has, including its own relationships.

Builder The builder view of Include connected_to(node.type = "ship")
Expression
Include
connected_to(node.type = "ship")

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connected_to(node.type = "ship").
After After: Include connected_to(node.type = "ship"). Shows 6 of 32 nodes.
Shows 6 of 32 nodes

Connection count and neighbour count

The built-in properties Connection count and Neighbour count are the quickest way to ask how connected a node is, and they are not the same number. A connection count adds up every connection. A neighbour count adds up the different nodes at the far ends, so several connections between the same two nodes make one neighbour.

The fixture has two such pairs. Father Mott is both Ines’s confessor and her old friend, which is two connections to one neighbour. Corra employs Quill, who reports on Corra, which is another.

Connection count: five or more connections

Five or more connections. Five nodes stay, and Ines is one of them: she has five connections.

Builder The builder view of Include node.connection_count >= 5
Expression
Include
node.connection_count >= 5

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include node.connection_count >= 5.
After After: Include node.connection_count >= 5. Shows 5 of 32 nodes.
Shows 5 of 32 nodes

Neighbour count: five or more neighbours

Five or more neighbours. Two of Ines’s connections go to Father Mott, so she has only four neighbours and drops out. In an expression this one is spelt node.neighbor_count, with the American spelling; the builder says “Neighbour count”.

Builder The builder view of Include node.neighbor_count >= 5
Expression
Include
node.neighbor_count >= 5

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include node.neighbor_count >= 5.
After After: Include node.neighbor_count >= 5. Shows 4 of 32 nodes.
Shows 4 of 32 nodes

Narrowing with via

A neighbour condition normally follows every connection. via limits it to connections that pass a test of their own, such as a type. It reads as “connected to a node where…, through a connection where…“.

Connected to a clue, by any connection

Without via, being next to a clue by any connection counts. That includes the two clues that contradict each other, and the locations where clues were found.

Builder The builder view of Include connected_to(node.type = "clue")
Expression
Include
connected_to(node.type = "clue")

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connected_to(node.type = "clue").
After After: Include connected_to(node.type = "clue"). Shows 10 of 32 nodes.
Shows 10 of 32 nodes

Connected to a clue, via Points to

With via set to “Points to”, only the connections of that type are followed. The two clues and the places where clues were found no longer count, and what remains is what the clues point at.

Builder The builder view of Include connected_to(node.type = "clue", via: type = "Points to")
Expression
Include
connected_to(node.type = "clue", via: type = "Points to")

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connected_to(node.type = "clue", via: type = "Points to").
After After: Include connected_to(node.type = "clue", via: type = "Points to"). Shows 6 of 32 nodes.
Shows 6 of 32 nodes

The test after via is a connection test, so it takes the same type, text and tags as “has a connection”.

Direction

Most connections have a direction: they point from one node to another. A neighbour condition can follow connections that point in to the node being tested, connections that point out of it, or any connection. Any is the default. The direction is always read from the node being tested. In these three examples the neighbour is Corra.

Direction in: Corra points at these nodes

In: a connection comes into the node from Corra. Corra employs Quill and is harbourmaster of Varrow, so those two match.

Builder The builder view of Include connected_to(node.name = "Harbourmaster Corra Vane", direction: "in")
Expression
Include
connected_to(node.name = "Harbourmaster Corra Vane", direction: "in")

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connected_to(node.name = "Harbourmaster Corra Vane", direction: "in").
After After: Include connected_to(node.name = "Harbourmaster Corra Vane", direction: "in"). Shows 2 of 32 nodes.
Shows 2 of 32 nodes

Direction out: these nodes point at Corra

Out: a connection goes out of the node to Corra. A clue points at her, the Last Lantern is captained by her, and Quill reports on her.

Builder The builder view of Include connected_to(node.name = "Harbourmaster Corra Vane", direction: "out")
Expression
Include
connected_to(node.name = "Harbourmaster Corra Vane", direction: "out")

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connected_to(node.name = "Harbourmaster Corra Vane", direction: "out").
After After: Include connected_to(node.name = "Harbourmaster Corra Vane", direction: "out"). Shows 3 of 32 nodes.
Shows 3 of 32 nodes

Direction any: either way round

Any finds all of them. Quill matches both of the earlier examples, and appears once.

Builder The builder view of Include connected_to(node.name = "Harbourmaster Corra Vane")
Expression
Include
connected_to(node.name = "Harbourmaster Corra Vane")

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connected_to(node.name = "Harbourmaster Corra Vane").
After After: Include connected_to(node.name = "Harbourmaster Corra Vane"). Shows 4 of 32 nodes.
Shows 4 of 32 nodes

Undirected connections

Some connections have no direction, such as “Siblings” or “Old rivals”. An undirected connection matches only any. It is neither in nor out, so a filter that asks for a direction drops it.

Ysolde and Father Mott are siblings, and that connection has no direction. Ysolde also lives at the cove, and that one points from her to it.

An undirected connection and direction in

With direction in, only the cove is found. Ysolde’s sibling is missing.

Builder The builder view of Include connected_to(node.name = "Ysolde Marsh", direction: "in")
Expression
Include
connected_to(node.name = "Ysolde Marsh", direction: "in")

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connected_to(node.name = "Ysolde Marsh", direction: "in").
After After: Include connected_to(node.name = "Ysolde Marsh", direction: "in"). Shows 1 of 32 nodes.
Shows 1 of 32 nodes

An undirected connection and direction any

With any, the undirected connection counts and Father Mott joins the cove.

Builder The builder view of Include connected_to(node.name = "Ysolde Marsh")
Expression
Include
connected_to(node.name = "Ysolde Marsh")

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connected_to(node.name = "Ysolde Marsh").
After After: Include connected_to(node.name = "Ysolde Marsh"). Shows 2 of 32 nodes.
Shows 2 of 32 nodes

At least N

Both conditions normally need just one match. The at least box sets how many. Leave it at 1 and nothing changes. It takes a whole number from 1 to 1,000.

On connected to it counts neighbours, and each neighbour counts once, however many connections lead to it. In the builder it reads “Connected … to at least [N] neighbours where”, with the direction choice in the gap.

Connected to at least 2 clues that point at them

Nodes that at least two clues point at. On this map only the chapel has that many.

Builder The builder view of Include connected_to(node.type = "clue", via: type = "Points to", direction: "in", at_least: 2)
Expression
Include
connected_to(node.type = "clue", via: type = "Points to", direction: "in", at_least: 2)

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connected_to(node.type = "clue", via: type = "Points to", direction: "in", at_least: 2).
After After: Include connected_to(node.type = "clue", via: type = "Points to", direction: "in", at_least: 2). Shows 1 of 32 nodes.
Shows 1 of 32 nodes

On has a connection it counts connections, and parallel connections each count. It reads “Has at least [N] connections where” in the builder.

Has at least 2 connections between the same pair

Nodes with at least two connections of type “Employs” or “Reports on”. Corra and Quill each have both. Written as “connected to at least 2 neighbours”, the same test would match nothing, because each of them has just the one neighbour.

Builder The builder view of Include connection(type = "Employs" OR type = "Reports on", at_least: 2)
Expression
Include
connection(type = "Employs" OR type = "Reports on", at_least: 2)

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include connection(type = "Employs" OR type = "Reports on", at_least: 2).
After After: Include connection(type = "Employs" OR type = "Reports on", at_least: 2). Shows 2 of 32 nodes.
Shows 2 of 32 nodes

In an expression, at least is a named argument at the end: at_least: 2. It is left out when it is 1. There is no “at most” or “exactly”, but you can write them with Not: “at most one” is NOT connection(…, at_least: 2).

Nesting

The condition inside “connected to” can itself contain a relationship condition, so a filter can reach across several steps.

Two steps: people beside a place that has a clue

Characters beside a place that has a clue. The inner step finds the locations with a clue as a neighbour, and the outer step finds the characters next to those locations.

Builder The builder view of Include node.type = "npc" AND connected_to(node.type = "location" AND connected_to(node.type = "clue"))
Expression
Include
node.type = "npc" AND connected_to(node.type = "location" AND connected_to(node.type = "clue"))

Before Before, with the filters off: the map shows all 32 nodes. Filters: Include node.type = "npc" AND connected_to(node.type = "location" AND connected_to(node.type = "clue")).
After After: Include node.type = "npc" AND connected_to(node.type = "location" AND connected_to(node.type = "clue")). Shows 6 of 32 nodes.
Shows 6 of 32 nodes

A filter can follow at most three relationship steps down any one path. The step a nested “connected to” takes counts, and so does each one inside it. “Has a connection” and the via test do not count, and neither does at least N. A fourth step is refused with “a selector follows at most 3 relationship steps”, and the map keeps the filter it already had.

The headline example on the Examples page uses all three:

X = connected_to(node.type = "clue", via: type = "Points to", direction: "in", at_least: 3)
C = node.type = "clue" AND connected_to(X, via: type = "Points to", direction: "out")
Include: C OR connected_to(C)

Reading it from the outside in, connected_to(C) is the first step. C is the clues that point at X, which is the second step, and X is the nodes that clues point at, which is the third. A filter with a fourth step in it is refused.