Aggregations
An aggregation is a calculated field that looks across all the entities related to this one and produces a single number from them. The classic examples:
- A character’s number of children (count related Characters via the Parent of relationship).
- A faction’s total membership (count related Characters via Member of).
- A noble house’s total wealth (sum the
valuefield across owned Items). - A general’s average loyalty among officers (average the
loyaltyfield on related Characters).
The result lives on the entity itself, just like any other auto-calculated field. As you create new related entities, the value updates the next time the entity is shown.
When to use an aggregation
Section titled “When to use an aggregation”Use an aggregation when the answer comes from counting or summarising other entities. If the answer comes from this entity’s own fields, you want a Formula instead. If it comes from one specific other entity, you want a Lookup.
| You want to… | Use |
|---|---|
| Count how many entities are related a given way | Aggregation, COUNT |
| Add up a number from each related entity | Aggregation, SUM |
| Average a number across related entities | Aggregation, AVG |
| Find the highest or lowest value among related entities | Aggregation, MAX or MIN |
| Collect every value into a list | Aggregation, LIST |
Setting up an aggregation
Section titled “Setting up an aggregation”- Make sure the relationship type you’ll aggregate over actually exists in your world. (You can check under Management → Relationship Types.)
- Add the field that’ll hold the result — usually a number for COUNT/SUM/AVG/MIN/MAX, or a list for LIST.
- Open Management → Entity Types, pick the type, switch to Behaviours, click Add Behaviour.
- Choose Auto-calculate, target the field you just made.
- Pick Aggregation as the calculation kind.
- Fill in the four parts described below.
- Save.
The four parts of an aggregation
Section titled “The four parts of an aggregation”Every aggregation answers four questions:
1. What kind of summary?
Section titled “1. What kind of summary?”| Kind | Result |
|---|---|
| COUNT | A whole number — how many related entities there are. |
| SUM | A number — add up a chosen field across them. |
| AVG | A number — average of a chosen field. |
| MAX | The largest value of a chosen field. |
| MIN | The smallest value. |
| LIST | A list — every chosen field’s value collected together. |
COUNT is the only one that doesn’t need to specify a field — it just counts entities. The other five all need to know which field on the related entities to summarise.
2. Which relationship?
Section titled “2. Which relationship?”Pick the relationship type to traverse. The picker shows the relationship types defined in your world; you can also enter a custom name if you’ve created one.
Examples:
- “Children” — relationship
PARENT_OF(outgoing, see below — this character is the parent). - “Total wealth” — relationship
OWNS(outgoing). - “Members” — relationship
MEMBER_OF(incoming).
3. Which direction?
Section titled “3. Which direction?”Relationships have direction. The aggregation needs to know which way to walk:
| Direction | Meaning |
|---|---|
| Outgoing | This entity points to others. (“Things this character owns.”) |
| Incoming | Others point to this entity. (“People who consider this character their parent.”) |
| Both | Either direction. Used for symmetric relationships like “Allied with”. |
If you’re not sure which direction you want, think about which entity is being created when the relationship is set up. If you click “Add owner” on a sword, the relationship is set up as Sword → Character — incoming from the character’s perspective.
4. Which field to summarise? (Optional)
Section titled “4. Which field to summarise? (Optional)”Skip this for COUNT — counts don’t need a field. For everything else, pick the field on the related entities whose values to summarise.
For SUM, AVG, MAX, MIN — the field must be a number. For LIST, any field type works.
Worked examples
Section titled “Worked examples”Count of children on a Character
Section titled “Count of children on a Character”- Calculation kind: Aggregation, sub-type COUNT
- Relationship:
PARENT_OF - Direction: Outgoing (this character is the parent in the relationship)
- Target field: (not needed for COUNT)
Result: a number. If the character has three child characters linked via PARENT_OF, the field shows 3.
Total wealth on a Character
Section titled “Total wealth on a Character”- Calculation kind: Aggregation, sub-type SUM
- Relationship:
OWNS - Direction: Outgoing
- Target field:
value(on the owned Item)
Result: the sum of value across every Item this character owns. As you create new owned items, the total updates.
Average loyalty across allies
Section titled “Average loyalty across allies”- Calculation kind: Aggregation, sub-type AVG
- Relationship:
ALLIED_WITH - Direction: Both (allied is symmetric — works either way)
- Target field:
loyalty_score
Result: the average of loyalty_score across every allied character.
List of skill names
Section titled “List of skill names”- Calculation kind: Aggregation, sub-type LIST
- Relationship:
HAS_SKILL - Direction: Outgoing
- Target field:
name
Result: a list of strings — the name of every related skill entity.
Tips and gotchas
Section titled “Tips and gotchas”The relationship type has to exist. If you type a custom relationship name into the editor, the editor checks against your world’s relationship types and rejects unknown names at save time. If you want a relationship that doesn’t exist yet, define it under Management → Relationship Types first.
The target field must exist on the related entities, not on this one. When picking value for “total wealth”, that’s the value field on Item, not on Character. The picker shows the fields available on the parent entity type, which is a UI limitation — the validator allows any field that exists. If your aggregation targets a different entity type, double-check the field name is spelled correctly.
Aggregations recompute when the entity is shown. Don’t worry about them going stale — they re-run on every display.
Keep them shallow. An aggregation that crawls across hundreds of related entities, each of which has its own aggregation, can get slow. One hop is the sweet spot.
Empty result vs zero. If a character has no children, COUNT returns 0. SUM, AVG, MAX, MIN with no related entities return empty. Wrap your formula consumers with coalesce(field, 0) if you need a number even when there’s nothing to sum.