Skip to content

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 value field across owned Items).
  • A general’s average loyalty among officers (average the loyalty field 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.

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 wayAggregation, COUNT
Add up a number from each related entityAggregation, SUM
Average a number across related entitiesAggregation, AVG
Find the highest or lowest value among related entitiesAggregation, MAX or MIN
Collect every value into a listAggregation, LIST
  1. Make sure the relationship type you’ll aggregate over actually exists in your world. (You can check under Management → Relationship Types.)
  2. Add the field that’ll hold the result — usually a number for COUNT/SUM/AVG/MIN/MAX, or a list for LIST.
  3. Open Management → Entity Types, pick the type, switch to Behaviours, click Add Behaviour.
  4. Choose Auto-calculate, target the field you just made.
  5. Pick Aggregation as the calculation kind.
  6. Fill in the four parts described below.
  7. Save.

Every aggregation answers four questions:

KindResult
COUNTA whole number — how many related entities there are.
SUMA number — add up a chosen field across them.
AVGA number — average of a chosen field.
MAXThe largest value of a chosen field.
MINThe smallest value.
LISTA 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.

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).

Relationships have direction. The aggregation needs to know which way to walk:

DirectionMeaning
OutgoingThis entity points to others. (“Things this character owns.”)
IncomingOthers point to this entity. (“People who consider this character their parent.”)
BothEither 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 SwordCharacter — incoming from the character’s perspective.

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.

  • 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.

  • 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.

  • 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.

  • 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.

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.