Modelling Complex Interactions
Most relationships just say that two things are connected — “Aragorn is a member of the Fellowship”. But some connections need to carry data: how much, how many per day, worth how much. Economies, crafting, supply chains, and logistics all live in that second category.
This page works through one concrete example — a currency system — to show what the relationship model can express directly, where it stops, and the clean way to model the parts it can’t.
The worked example: the Vermark currency
Section titled “The worked example: the Vermark currency”A world where the economy matters. We want to model:
- Copper Vermark, Silver Vermark, and Gold Vermark as Items (the
Itemtype already includes acurrencyitem type). - A Copper Vermark is made from 0.01 of a Copper Ingot.
- A Copper Vermark is worth 0.05 Silver Vermark.
- Copper Vermarks are minted at three different mints, each with a different daily output: Aelindor Mint (300/day), Solarius Mint (700/day), Stormheaven Mint (900/day).
Every one of those connections carries a number. That’s the interesting part.
Approach 1 — Relationship properties (the lightweight path)
Section titled “Approach 1 — Relationship properties (the lightweight path)”Every relationship in MythTapestry is an edge that can carry extended properties — text, numbers, selects, booleans, dates — captured per link. And a multi-entity reference field lets a single field hold many links, each with its own property values.
That’s enough to express the whole example directly:
| What we want to model | How | Carries |
|---|---|---|
| Copper / Silver / Gold Vermark | Items, item_type: currency | — |
| Made from 0.01 Copper Ingot | A reference to the Copper Ingot Item + a number property quantity | quantity = 0.01 |
| Worth 0.05 Silver Vermark | A reference to the Silver Vermark Item + a number property amount | amount = 0.05 |
| Minted at three mints, different outputs | One multi-reference field to the three mint Locations, each link carrying its own number | output_per_day = 300 / 700 / 900 |
The last row is the one that surprises people: three links on a single “minted at” field, each with a different output_per_day. Because each link is its own edge, each carries its own numbers. The same mechanism powers smaller cases too — like an event participant’s role, which is just a single-select property on the participation edge.
This approach was validated end-to-end against a real world: the three minting edges, the ingredient quantity, and the currency value all store and read back exactly as entered.
Where Approach 1 stops
Section titled “Where Approach 1 stops”Relationship properties are powerful but deliberately simple. Four limits are worth knowing before you build a large economy on them.
Approach 2 — Promote the connection to an entity (reification)
Section titled “Approach 2 — Promote the connection to an entity (reification)”Approach 1 strains the moment a “connection” needs to point at several entities at once, or carry its own relationships. That’s the signal to stop modelling it as an edge and make it a thing — an entity in its own right. This is called reification.
Take production. A single minting run really involves: an output (Copper Vermark), one or more inputs (Copper Ingot ×0.01), a facility (the mint), and a rate (per day). Trying to cram all of that onto one edge fails limit #1 — an edge can’t reference the output and the input and the facility.
Instead, create a Recipe (or Production) entity type:
- In Management → Entity Types, create a custom type — call it
Recipe. - Give it reference fields: Output (→ Item), Inputs (→ Items, multi-reference, each with a
quantityproperty), Facility (→ Location or Organization), and number fields like Output per day and Cost. - Now “Copper Vermark, minted at Aelindor Mint from 0.01 Copper Ingot, 300/day” is one Recipe entity — fully queryable, with each mint’s run as its own record.
A worked Recipe for the example:
| Field | Type | Value |
|---|---|---|
| Output | Reference → Item | Copper Vermark |
| Inputs | Multi-reference → Item (+ quantity) | Copper Ingot (quantity: 0.01) |
| Facility | Reference → Location | Aelindor Mint |
| Output per day | Number | 300 |
| Operating cost | Number (in a currency Item, via a reference) | … |
Three mints producing Copper Vermark become three Recipe entities — and now the maths you couldn’t do in Approach 1 becomes easy: the total daily output is an aggregation that sums the Output per day field across all Recipes whose Output is Copper Vermark — because that number now lives on an entity, not an edge.
Which approach should I use?
Section titled “Which approach should I use?”| Your connection… | Use |
|---|---|
| …only needs a scalar or two (a quantity, a rate, a role) | Relationship property (Approach 1) |
| …needs each of many links to carry its own value (3 mints, 3 outputs) | Multi-reference field with properties (Approach 1) |
| …needs to reference several entities at once (output + inputs + facility) | Reify it as an entity (Approach 2) |
| …needs totals, averages, or rankings over its numbers | Reify it — only entity fields aggregate |
| …is itself a thing in the world’s history (a specific trade, a production run) | Reify it |
A good rule of thumb: if you find yourself wishing a relationship property could point at another entity, or wanting to add up numbers that live on edges — that connection wants to be an entity.