Magical gene / no coat effect

Milk

What comes out when you put a bucket under the horse. Ordinarily milk, from a mare, as everywhere else in the game — but two copies of one magical allele and any grown horse fills the bucket with water, and two of the other and it fills with lava. One of each and there is no foal at all.

Crossing two of them

It paints nothing

Every one of the five outcomes is a wildType, which in this model means “changes nothing about the coat” — the same trick the thirteen non-coat loci and sex use. So affectsCoat() is false, the locus is left out of a horse’s texture key, and the genotype gallery collapses it to a single entry. Three alleles, no growth in the catalogue at all.

The cost is that a lava horse is indistinguishable from an ordinary one until somebody puts a bucket under it. That is a real gap and it is logged as one — a marking allele would be the fix, and would want to be part of the locus rather than bolted on.

Its gene carrot

Gene key
horsegenetics.milk
Priority
130 (magical band)
Alleles
Watr Lava n
Combinations
6 — 5 carryable, 5 outcomes
Outcomes
mares-milk, milk-carrier, water-milk, lava-milk, milk-lethal
Default allele
n
Wild frequency
Watr 8%, Lava 6% per allele
Founder draws
1 × nextFloat()
Coat effect
none, ever — every outcome is a wild type
Built 2026-09-04, not yet play-tested

The combination table, the founder distribution and the embryonic lethal are unit-tested; nothing about the actual bucket interaction has been seen in-game. Checklist on To be verified.

The combination table

CombinationOutcomeWhat a bucket gets
n/nmares-milkMilk, from a grown mare
Watr/n, Lava/nmilk-carrierMilk, from a grown mare — nothing else shows
Watr/Watrwater-milkWater, from any grown horse
Lava/Lavalava-milkLava, from any grown horse
Watr/Lavamilk-lethal— the embryo never develops

Both magical alleles are recessive to the wild type and to each other, which makes this the mod’s cleanest double-carrier locus. About one wild horse in seven carries Watr and one in nine Lava, and neither shows. You cannot catch a lava horse. You have to notice that two ordinary-looking mares threw one, or breed a line and find out — which is the design of the health loci pointed at something worth having instead of something to avoid.

The lethal

Watr/Lava is an embryonic lethal: the pairing simply produces no foal. It is the same code path as MET — the Mendelian draw is untouched and the breeding handler reads the genotype it drew and cancels the birth, so the odds stay the ordinary one in four for two carriers and the check is one branch in one place. Two consequences follow:

  • canOccur is false, so the genotype gallery gives it no pen and does not count it — the same rule that rules out a Y/Y horse;
  • expressionOf still answers for it, because parsing is tolerant and a hand-written code string can name any combination.
Not a health disorder, and deliberately not switchable

Every other lethal in the mod is a HealthContribution, so the server’s health.mode setting can switch it off. This one is not. That setting governs genetic disorders, and two magical fluids refusing to share an embryo is not a disorder, it is the rule of the gene. Turning the disorders off must not quietly make a water/lava horse possible.

How it reaches the game

Milk is one of the genes that does its whole job through the effects vocabulary rather than through the coat. It implements AbilityContribution and hands back a single yield per combination:

That is the same record a data-driven gene’s effects block parses into, so the NeoForge translator (server/GeneYieldHandler) needed nothing new but minecraft:lava_bucket in its output table.

OutcomeConditionCooldown
mares-milk / milk-carrieradult, female, tamed, at her own full health24 000 ticks (once a day)
water-milkadult200 ticks
lava-milkadult1200 ticks

Water and lava are a rare double-recessive novelty, not a dairy — a renewable lava source that walks recharges six times slower than water, and both stay on short cooldowns. Milking proper is once-per-Minecraft-day now (the mod’s standard time gate), on the per-horse HorseCooldownsAttachment.

The milking rules — built 2026-09-05

Every rule that used to be listed as unbuilt now is, as effects-vocabulary additions rather than a special case in the interaction handler — so every gene gets them:

  • Tamed + own-max health — the milk yield’s when is {adult, sex_female, tamed, full_health}. The full_health flag measures against this horse’s max, so a genetically frail mare is milkable at 4 hearts.
  • Milking a stallion kicks you — a second yield with an empty produces, deniedDamage 1 and a message; the deniedMessage/deniedDamage pair is the else-branch a bare yield could not express.
  • A foal says it has nothing — the same shape, deniedDamage 0.
  • On cooldown the mare sends “nothing to give yet” rather than eating the click silently.

Still open: a tamed but hurt mare gets neither milk nor a mount and no message (no denial yield covers that case).

Why milk is a mare’s and lava is not

The wild type keeps the ordinary rule: milk comes from a grown mare. Water and lava are not milk, and come from any grown horse of either sex. The asymmetry is deliberate — the ordinary reading of the locus stays ordinary, and the magical readings are visibly not. It also makes a lava stallion worth keeping, which matters for a locus whose only route to the good outcomes is a breeding programme.