Skip to content

Gene Files

Gene files live in data/<namespace>/gene/<path>.json and use townstead:gene/v2.

{
"schema": "townstead:gene/v2",
"type": "pheno:attribute",
"display_name": "Strong",
"description": "Increases attack damage.",
"category": "body",
"dominance": "dominant",
"locus": "my_pack:strength",
"weight": 1,
"attribute": "minecraft:generic.attack_damage",
"amount": 2.0,
"operation": "add"
}
FieldTypeRequiredNotes
schemastringyestownstead:gene/v2.
typestringyesGene type key.
display_namecomponentnoDisplay name for UI and catalogues.
descriptioncomponentnoLonger help text.
categorystringnoDefaults to general.
dominancestringnodominant by default, or recessive.
locusidnoInheritance slot. Some gene types provide a default.
weightintegernoGene expression tie-break weight. Minimum 1.
variantsobjectnoNamed variants.
resourcesobjectnoLocal companion resources for this gene.

variants turns one gene file into multiple inherited options.

{
"schema": "townstead:gene/v2",
"type": "townstead_roots:eyes",
"display_name": "Eyes",
"variants": {
"round": {
"display_name": "Round Eyes",
"weight": 4,
"texture": "my_pack:textures/face/eyes/round.png"
},
"glowing": {
"display_name": "Glowing Eyes",
"weight": 1,
"texture": "my_pack:textures/face/eyes/glowing.png",
"glow": true
}
}
}

Each variant inherits the gene’s shared fields and adds its own config. Variant weight controls founder rolling and tie-breaking between two carried variants of the same gene.

A locus is the inheritance slot where related genes compete.

Genes at the same locus behave like different versions of the same inherited trait. Genes at different loci can both be expressed.

Use an explicit locus when two separate gene files should compete for the same inherited slot. For example, a species can define the usual eye shapes, while a lineage can define a narrower eye set that replaces it:

{
"schema": "townstead:gene/v2",
"type": "townstead_roots:eyes",
"display_name": "Moon Elf Eyes",
"locus": "my_pack:eyes",
"variants": {
"silver": {
"display_name": "Silver Eyes",
"weight": 4,
"texture": "my_pack:textures/face/eyes/silver.png"
},
"luminous": {
"display_name": "Luminous Eyes",
"weight": 1,
"texture": "my_pack:textures/face/eyes/luminous.png",
"glow": true
}
}
}

If this lineage gene and the species eye gene both use my_pack:eyes, only one eye-shape gene is expressed at that locus. If each gene has its own locus, both can be kept independently.

A gene can declare local resources. Each resource becomes a real pheno:resource gene with a derived id of <gene_id>/<resource_name>.

Inside the same gene, a bare "resource": "mana" or "compared_to_resource": "mana" reference is rewritten to the derived id.

{
"schema": "townstead:gene/v2",
"type": "pheno:active_ability",
"display_name": "Vault",
"cooldown": 60,
"resource_cost": {
"resource": "mana",
"amount": 10
},
"action": {
"type": "pheno:jump",
"strength": 1.2
},
"resources": {
"mana": {
"max": 40,
"regen": 1,
"regen_interval": 20
}
}
}

Companion resources ride along with the parent gene’s expression, so they tick and sync only when the parent gene is expressed.