Magical recessive / no coat effect
LYCAN — the werewolf locus
A horse with two matching copies stops being a horse at nightfall. Not a horse wearing a wolf: a real wolf, which breeds with wolves, is tamed with bones, and is a horse again at dawn with the same name and the same pedigree. Thirty-seven shapes share the locus, and every one of them is recessive to the wild type and to each other.
Crossing two of them
Two copies of the same allele, or nothing
Wlf/n is a horse. Wlf/Cat is also a
horse — two shapes, and it settles on neither. Only a matched pair
shifts.
That is what makes a locus this wide worth breeding rather than a slot machine. If any one of thirty-seven alleles showed, a shifter would be common and which animal you got would be luck. Requiring the same allele twice makes it a search with a target: two wild shifters caught in different biomes are probably different animals, and their foals are horses. The disappointment is the game.
| Combination | Outcome | What happens at dusk |
|---|---|---|
n/n | wild | nothing |
Wlf/n | lycan-carrier | nothing — and never a founder |
Wlf/Cat | lycan-mismatched | nothing; both shapes are carried and both are passed on |
Wlf/Wlf | lycan-wlf | it becomes a wolf |
The mismatched horse is its own named outcome rather than a fold into the wild type, because it is a genuinely different thing to be holding: it is one parent of two different lines at once.
Identity survives the night
The horse goes into an attachment on the animal, as its complete
Entity.saveWithoutId tag — which on NeoForge carries the
mod’s data attachments as well. So the record, the name, the pedigree, the
bond, the cooldowns and the cowboy’s brand all
cross the night untouched, and so does the horse’s UUID.
That last one is the load-bearing part: a shifted horse is the same horse, not a lookalike, so the ancestry database, the breeding roster and the stalls are all undisturbed by the whole business.
Unusual, and worth being explicit about. The alternative was to keep the horse alive somewhere off-map and teleport it back, which needs a holding dimension, a reaper for the ones whose animal died, and a rule for what happens when the chunk unloads.
A tag that travels with the animal has none of those problems: unload the chunk
and both go to disk together, and kill the animal and the horse dies
with it — which is exactly what should happen, and is why the
attachment is deliberately not copyOnDeath.
What a shifted animal does that an ordinary one does not
| Behaviour | Detail |
|---|---|
| It trails a cloud | A faint puff of coloured dust round the body whenever it moves on the ground — “surrounded by”, not “trailing from”. The colour is epigenetic, and it is the only way to tell a were-cow from a cow. |
| It holds a grudge | Hit it and it follows and strikes back — the wolf’s temper, given to every form, so a were-chicken really will chase you across a field. It forgets at sunrise or after three seconds without line of sight, the same memory a wild horse herd uses. |
| It cannot be ridden | The point of the gene is the night you cannot ride home. |
The grudge is one goal rather than the usual melee-plus-target pair, because
the forms have no attack: a chicken has no
ATTACK_DAMAGE attribute at all, so the vanilla melee goal has nothing
to read. Adding the attribute to thirty-seven vanilla mob types would hand every
sheep, cod and wandering trader in the world an attack stat it never had, for the
sake of the one in ten thousand that is secretly a horse. Dealing a flat three
points by hand touches nothing that is not already ours.
The thirty-seven shapes
Every vanilla mob in a non-hostile spawn category — creature, ambient, water creature, water ambient, axolotl, underground water creature — minus the horse family, because a horse that turns into a horse at night is not a gene.
That is why the list contains a pufferfish and a wandering trader without
anybody having to defend either, and it is why the two golems, the villager,
the copper golem and the mannequin are out — they are
MobCategory.MISC.
The mob ids are strings, because common/ may not import
Minecraft, and the translator resolves them against the live registry. An id
this game version has never heard of simply never shifts, and says so once in
the log.
| Allele | Shape | Allele | Shape | Allele | Shape |
|---|---|---|---|---|---|
Aly | Allay | Arma | Armadillo | Axo | Axolotl |
Bat | Bat | Bee | Bee | Cml | Camel |
Cat | Cat | Chk | Chicken | Cod | Cod |
Cow | Cow | Dol | Dolphin | Fox | Fox |
Frg | Frog | Glsq | Glow squid | Gt | Goat |
Ghst | Happy ghast | Lma | Llama | Mshr | Mooshroom |
Ntls | Nautilus | Oce | Ocelot | Pnd | Panda |
Prt | Parrot | Pig | Pig | Plr | Polar bear |
Pff | Pufferfish | Rbt | Rabbit | Slm | Salmon |
Shp | Sheep | Snf | Sniffer | Sqd | Squid |
Strd | Strider | Tdp | Tadpole | Tlma | Trader llama |
Trpf | Tropical fish | Trt | Turtle | Wtr | Wandering trader |
Wlf | Wolf | — | |||
Finding one
Each shape sits at 0.03% of founders, homozygous, and there are no wild carriers and no wild mismatches — the same rule as the particle locus, for the same reason: a recessive whose carrier is invisible has to put its expressing combination in the wild, or the allele can only ever be found by accident.
So about one wild horse in ninety shifts at night, and any one particular animal is roughly one horse in three thousand three hundred. Every shifter you meet in the world is one you can watch shift; every carrier in the world is one somebody bred.
Dusk, dawn, and dimensions with no night
The check is Level.isDarkOutside() rather than
!isBrightOutside(), and those are not the same thing: both are false in
a dimension with a fixed time of day. Asking it this way makes the Nether, the End
and the horse dimension permanent day
for this gene, which is the right answer — a place with no nightfall should
not hold a horse in wolf shape forever.
Its gene carrot
The known carrot hands over one copy, never two — a shifter is the reward for breeding two carriers of the same shape, and a carrot that produced one outright would skip the entire locus.
- Gene key
- horsegenetics.lycan
- Priority
- 152 — after rainbow dust; a code-order slot only
- Alleles
- 37 shapes + n — see the table
- Outcomes
- wild, carrier, mismatched, and one per shape
- Shows when
- two copies of the same allele
- Default allele
- n
- Wild frequency
- 0.03% per shape — about 1.1% of founders shift; no founder is a carrier
- Founder draws
- 1 × nextFloat()
- Coat effect
- none, ever
- Epigenetic
- one colour — the cloud the shifted animal trails
This gene discards a horse entity and creates a different one, twice a day. Written against 26.1.2 sources and never watched happen. The things to check first are on To be verified §0-AH, and the top of that list is: does a shifted horse come back with its name, its record and its pedigree intact?
The cloud colour
This gene’s one epigenetic value, drawn on the allele copy and inherited with it, held to a bright saturation and value like every other rolled colour in the mod — a faint cloud round a wolf at night is the whole visual, and one that rolled a muddy olive would read as a bug rather than as variety.
It is also the only heritable thing about a shifted animal, which makes it the only thing to breed for once you have the shape: a line of were-cats can be bred toward a particular colour of cat.
What lives where
The gene owns the genetics and the cloud colour and nothing else; the shift is
hand-written behaviour in the game module. That is the same split
dhampir makes, for the same reason: each of these
would be an effects verb with exactly
one user, and the effects vocabulary is meant to be things a data-driven
gene would reach for.
| File | What it owns |
|---|---|
common/genetics/genes/LycanGene.java | the alleles, the matched-pair rule, the founder table, the cloud colour |
neoforge/data/LycanShift.java | the attachment: the horse’s tag, the cloud colour, the mob id |
neoforge/server/LycanthropyHandler.java | the swap at both ends of the night, the cloud, the riding ban, the aggro hook |
neoforge/server/LycanTemperGoal.java | the grudge: chase, strike, forget at sunrise or on lost sight |
Why it swaps the entity instead of drawing a skin
The roadmap scoped this “render-layer first, entity-swap second”. The requirement overruled that, and it is worth writing down why, because a render layer is by far the cheaper thing to build.
Up to and including breeding with real members of that species. A horse wearing a wolf skin cannot be bred with a wolf. It cannot be tamed with a bone, sheared, bucketed, dyed, fed a cookie, or leashed to a fence post the way its animal can. Every one of those would have to be hand-written, and each one would still be wrong for the next mob on the list.
Putting the real entity in the world gets the entire list for free, correctly, including whatever other mods do to vanilla animals.
The “and no others” half falls out of the same decision. While
it is a wolf there is no Horse in the world, so none of this
mod’s own horse interactions —
transfer papers, shearing,
gene carrots, the stall reader — can see it at
all. The one exception that has to be enforced by hand is riding:
six or so of the shapes are rideable animals, and the mount is cancelled.
common/genetics/genes/LycanGene.java,
neoforge/server/LycanthropyHandler.java