Magical gene / phase 3

Mane colour

A mane in any colour there is — solid, or banded, or both at once in two different colours. The colour is not a property of the allele but of the allele copy, drawn from a continuous hue circle, so it travels with the copy and a foal inherits its parent’s exact shade.

What it does

What to look for: a mane in any colour at all — solid, banded, or two colours at once.

The exact shade is inherited. The colour belongs to the copy rather than to the gene, so a foal gets its parent's precise shade rather than a fresh roll. That means you can breed a particular colour and keep it, which is unusual here.

Pair it with tail colour, a separate gene, if you want the two ends to match — or deliberately not to.

Crossing two of them

Its gene carrot

Gene key
horsegenetics.mane_color
Priority
112 (magical band, before magic zebra)
Alleles
Mnsld Mnstrp n
Combinations
6, all carryable — 4 outcomes
Outcomes
wild, solid, striped, solid-striped
Default allele
n
Wild frequency
Mnsld 2.0%, Mnstrp 1.5% per allele → ~7% of wild horses
Founder draws
1 × nextFloat()
Deterministic
no — the colour is per-copy
Strength
88% of the way to the colour
Twin locus
Tail colour
Built 2026-09-04, not yet play-tested

Sample bakes look right — solid manes read as one colour, bands are wobbled rather than ruled, and the heterozygote shows two distinct colours. Nothing has been seen on a 3D horse. Checklist on To be verified.

The combination table

CombinationOutcomeWhat the mane looks like
n/nwildIts coat colour
Mnsld/n, Mnsld/MnsldsolidOne bright colour, whole mane
Mnstrp/n, Mnstrp/MnstrpstripedBands of one bright colour across the coat colour
Mnsld/Mnstrpsolid-stripedTwo colours: the solid copy’s base with the striped copy’s bands over it

The heterozygote is the interesting one

Mnsld/Mnstrp is not a compromise between the two and it is not one of them winning. It is both, at once, in two different colours — a look neither allele can make on its own, which is exactly what earns it its own row in the table.

It also needs something no other gene in the mod has needed: the epigenetics of each copy separately. Every other non-deterministic gene asks ctx.epigeneticsFor(key), which answers “what does this horse show at this locus” — one locus, one look, one seed. Here both copies paint at the same time, and asking for the expressed one would paint the stripes in the base colour, which is a horse with no stripes.

common/genetics/genes/HairColorGene.java
private ColorField paintBoth(CoatBuildContext ctx, PigmentView coat, ColorView accumulated) {
    Hair base = draw(ctx.epigeneticsForCopy(key, 0));   // the solid allele - declared first
    Hair band = draw(ctx.epigeneticsForCopy(key, 1));   // the striped one
    ...
}

The solid allele is declared first in alleles(), and an AllelePair orders by declaration, so slot 0 is the solid copy and slot 1 is the striped one. No guessing.

Where the colour lives

Each allele copy carries one epigenetic value: its colour, drawn as a bright hue off that copy’s seed. There is no palette and no list — hue is uniform over the whole circle, and two unrelated horses agreeing on a colour is essentially impossible.

common/coat/pattern/HairPattern.java
public static int randomBrightColour(Rng rng) {
    float hue        = rng.nextFloat();
    float saturation = 0.60f + rng.nextFloat() * 0.40f;
    float value      = 0.62f + rng.nextFloat() * 0.38f;
    return hsvToRgb(hue, saturation, value);
}

Saturation and value are held well up on purpose. A magical mane that rolled a muddy olive would read as a bug, and the whole point of the gene is that you can see what a horse is carrying.

Because the colour is on the copy, it is heritable: breed a horse with a mane you like and its foals get that exact colour, not a new roll. That is what makes a particular horse worth keeping rather than just its genotype.

Painting toward, not with

The paint walks each texel 88% of the way from what it already looks like to the target colour, which is the TOWARD move every hair gene here makes and for the same reason: flat paint throws away the strand shading the natural phase and the template gave the mane and leaves a dead rectangle. Short of the whole way, the mane is unmistakably the new colour and still reads as hair.

Bands run across the mane’s longest axis, wobbled off straight by BodyNoise. Which axis that is is worked out from the part’s own bounds rather than hard-coded, because a mane is a long thin box and a tail is a short fat one and both are rotated out of the world axes by their rest pose — see HairPattern.axesBySpan.

Where it sits in phase 3

Priority 112: after the two loci deliberately parked at the bottom of the magical band (suit at 102, hood at 103), so a coloured mane wins over a pink one; before magic zebra (120), so zebra stripes still black out a coloured mane rather than the other way round. Both of those are choices, not accidents — see the magical ordering.

A foal shows nothing here

The foal mesh has no MANE part at all (see body space), so the colour arrives with adulthood. Its twin locus does show on a foal, which makes the tail the earlier of the two to read off a young horse.

Three alleles is a starting point

A third pattern — dip-dyed, tipped, roots — is one more allele, one more expression and one more painter, and every existing combination keeps its meaning. That is the combination table doing its job: adding an allele to a dominance-ranked gene would mean deciding where it ranks against the other two, and there is no answer to that question here.

Source: common/genetics/genes/ManeColorGene.java, HairColorGene.java, coat/pattern/HairPattern.java