Skip to content

Heritage

Heritage answers: what ancestry fractions does this individual carry?

Heritage profiles name ancestry fraction patterns. They do not create ancestry by themselves; they label a carried heritage map.

Path: data/<namespace>/heritage/<path>.json

Schema: townstead:heritage/v1

FieldTypeRequiredNotes
schemastringyestownstead:heritage/v1.
display_namecomponentnoShown when the match wins.
demonymobjectnoDemonym for this mixed heritage.
backstorycomponentnoOptional descriptive text.
prioritynumbernoHigher priority wins when more than one profile matches. Defaults to 0.
matchobjectone of match or lineagesAncestry fraction requirements.
lineagesobjectone of match or lineagesLineage share requirements, in the same form as match.
open_lineagesbooleannotrue lets lineages the profile doesn’t list make up the rest. Defaults to false.
genesid arraynoGenes the heritage grants in its own right, expressed on top of what was inherited. They are not carried, so a child only expresses them by matching the profile too. A granted gene replaces the inherited gene at its locus, so a profile can change how a mix looks. For example, a Half-Cat profile can grant a human face and cat ears in the colour of the hair. A granted gene with variants picks one per individual, stable for that villager.
hairboolean or objectnoTurns MCA hair on or off and limits its colours for characters that match this profile. See Hair Policy.
{
"schema": "townstead:heritage/v1",
"display_name": "Half-Moon-Elf",
"priority": 10,
"match": {
"my_pack:human": { "min": 0.45, "max": 0.55 },
"my_pack:elf": { "min": 0.45, "max": 0.55 }
}
}

Each match entry can be a bare number for an exact fraction, or an object with min and max.

A heritage profile matches when every listed ancestry is inside its range. The person can carry a small amount of ancestry not listed in the profile, but the unlisted total must be 0.05 or less.

For example, the Half-Moon-Elf profile above matches:

Heritage FractionsResult
50% human, 50% elfMatches.
65% human, 35% elfDoes not match because it is outside the half-ancestry range.
50% human, 45% elf, 5% dwarfMatches because the unlisted ancestry is within the 0.05 allowance.
50% human, 40% elf, 10% dwarfDoes not match because too much ancestry is outside the profile.

If more than one profile matches, the profile with the highest priority wins. Use priority when a broad profile and a more specific profile can both apply.

{
"schema": "townstead:heritage/v1",
"display_name": "Moon-Blooded",
"priority": 20,
"match": {
"my_pack:elf": { "min": 0.45, "max": 0.75 },
"my_pack:human": { "min": 0.2, "max": 0.55 }
}
}

This profile could overlap with Half-Moon-Elf, so its higher priority lets it win for the narrower identity.

If no heritage profile matches, near-pure heritage keeps its dominant ancestry/root name, and mixed heritage falls back to a generated two-largest label. An ancestry carried mostly (70% or more) through one lineage is named by that lineage, For example, the child of a Moon Elf and a Feline parent shows “Moon Elf-Feline”, not “Elf-Bestial”.

lineages matches lineage shares the way match matches ancestry shares. Use it to name a cross inside one ancestry:

{
"schema": "townstead:heritage/v1",
"display_name": "Steam Drake",
"priority": 20,
"lineages": {
"my_pack:fire_drake": { "min": 0.3, "max": 0.7 },
"my_pack:ice_drake": { "min": 0.3, "max": 0.7 }
},
"genes": ["my_pack:steam_drake/scalding_breath"]
}

By default, unlisted lineages count against the profile in the same way as unlisted ancestries. That breaks a profile that names one side’s lineage but should accept any partner, because a human parent may be plain (no lineage) or come from a human lineage. Set open_lineages and let match bound who the partner can be:

{
"schema": "townstead:heritage/v1",
"display_name": "Half-Cat",
"priority": 15,
"match": {
"townstead_roots:human": { "min": 0.3, "max": 0.7 },
"my_pack:bestial": { "min": 0.3, "max": 0.7 }
},
"lineages": { "my_pack:feline": { "min": 0.3, "max": 0.7 } },
"open_lineages": true
}

A common set of tiers for mixes with humans:

ShareNameBands
About halfHalf-Cathuman 0.3-0.7, the other 0.3-0.7
About a quarterCatbloodedhuman 0.7-0.9, the other 0.1-0.3
About three quartersThe lineage’s own namehuman 0.1-0.3, the other 0.7-0.9

For example:

LayerExample
SpeciesHumanoid
AncestryElf
LineageMoon Elf
HeritageHuman father plus Moon Elf mother can match Half-Moon-Elf.
Root ShapeSeed Heritage
Root with ancestry and lineage100% that ancestry, and 100% that lineage.
Root with only an ancestry100% that ancestry, with no lineage shares.
Legacy or malformed root without ancestry/lineageEmpty heritage map.

Children average their parents’ heritage maps, by ancestry and by lineage.