Project
To be verified
The rolling runClient checklist. Open issues are
reproducible in-game and not yet fixed; still to verify is built
but not yet confirmed in a play session. Confirmed items are
deleted, not ticked — the
session log’s “Owner-verified in-game”
entries are the permanent record.
Spawn Test Horse World (DebugTestWorldHandler.fillInventory)
hands out one hotbar at a time: themed batches covering what is below, a batch deleted once worked through, batch 1 on login. Behaviour first (owner, 2026-09-11: test “stuff that isn't just does this look pretty in-game”) - batches 1 and 2 are §0-BT's own ranking of what fails badly rather than visibly, and most of batch 1 is left running rather than watched and the rest with /testkit n
(/testkit alone lists them; each batch's legend ends with a clickable link to
the next). Swapping a batch empties the hotbar only. Its preset eggs carry a genotype and no epigenome, so every horse from one egg rolls its own numbers - knob-placed marks land somewhere new each time. Every batch that tames carries a
stick, every one that breeds carries golden carrots. Two clickable /tps on
login go to the nearest plains village and dark forest.
Four of those tests need files the kit cannot make, so the dev run's
run/phc/ was prepared for them on 2026-09-11 and a dedicated server
confirmed all four load: breeds/kit_forest_paint.json (chestnut paints, dark
forest), kit_night_cremello.json (dark forest, night only),
kit_broken_gene.json (logs a missing-gene warning, loads anyway),
kit_zz_duplicate_friesian.json (refused); genes/aurora.json (the
example gene, “1 dropped in”); and breed-spawning.toml with the
Friesian moved to dark forest only and the Morgan switched off. Delete them to put the
dev run back.
Those six files are in the repo now, at
neoforge-26.1.2/tools/testkit/ — whose README.txt is
also the one-page answer to “how do I start testing”: the button, the
/testkit commands, the fixed plains seed and the two things that waste
an hour (rebuilding under a live client; runServer while the client
holds run/). It has a note saying how to put the drop-ins back
— they had only ever existed in the .gitignored
run/phc/, which is to say on one laptop, so a fresh clone could not
reproduce any of the four checks.
§0-DD — The ward test that gap 210 said could not be run (2026-09-13, NOT looked at)
At the far end of the yard: a block of cyan wool on the walkway, and thirty blocks past it two identical dark chambers, one holding a warded horse and one holding a plain one. Stand on the wool overnight.
Why it is built this way, because every dimension of it is load-bearing
- Two chambers, not one. A warded chamber with no zombies in it proves nothing on its own — it is equally consistent with a working ward, a broken spawn rule, a mistake in the biome, and the player having wandered too close. The control is the experiment. The reading is the difference between two counts, which is immune to all four at once.
- Thirty blocks away, and that is the point. Gap 180: vanilla never naturally spawns a monster within 24 blocks of a player, and the ward reaches 8 to 16 — entirely inside the radius where nothing was going to spawn anyway. Every previous attempt at this test was standing next to the horse, which can only ever prove something you already had for free. Measured, the nearest corner of each chamber is 32.3 blocks from the wool.
- Equally far from both, to 0.00 blocks, by symmetry about the walkway — otherwise the nearer chamber spawns more for a reason that has nothing to do with the gene.
- Thirty-four blocks apart from each other, because the ward reaches at most sixteen. Any closer and the warded horse could be suppressing the control, which would turn a working ward into a null result.
- The control has a horse in it too, a plain one, so the two chambers differ in exactly one thing. An empty control would also differ in “has an entity in it”.
Pass: the control fills and the warded chamber does not. Both empty means the spawn rule is wrong rather than the gene — which is precisely what the control is there to tell you, and what no previous version of this test could have distinguished. The census counts the creatures in each chamber every two minutes and every spawn logs its reason, so the morning reading is two columns of numbers rather than an impression.
A chamber with its door open is a lit chamber, and a lit chamber spawns nothing. That would read as a perfect ward on both sides.
§0-DC — Four coat genes redrawn, and a biome that spawns zombies (2026-09-13, NOT looked at)
- Rainbow drip was never drip-shaped. It was five stacked
WAVES— horizontal sine bands — where ooze drip, the one that came back “looks GREAT”, is built onGOO: the mask that actually makes a drip, with separate runs, their own lengths, a bulb and a wobble. It now uses ooze's exact geometry and keeps its own colouring. The ramp had to be respanned too — it ran 0.42 to 0.7, which was where the bands sat, and the drips hang from 0.74 downward, so the whole rainbow would have been painted above them. - Gilded crackle's seam was one flat gold. Metal needs a value
range across the groove, so the seam is three concentric bands now — a dark
shadowed groove, the gold, and a bright specular lip — by painting the same
inverted
CRACKLEat three widths, widest first. Three layers became five. - Contour cells, at the third attempt. One patch was swallowing a
barrel. Raising the threshold and shrinking the patch alone were both refused by
DeadLayerTest, which is the thing worth remembering: the nested rings have to fit inside a patch and the gaps are measured in cells, so the motif only shrinks proportionally. Patch 14→10, cell 9→6, and every gap scaled by two thirds. That passed. - Starburst's pale form read as one flat white shape because its
whole palette ran
#7a7a7ato#ffffff— six layers of structure inside a third of the value range, several of them thin rings, with a white core to swallow them. The structure was always there; it had no contrast to show it with. The spikes, shards, outline and inline are pulled well down; the core stays white, because the core is the light.
A new biome, horsegenetics:debug_pens, replaces
minecraft:the_void and carries zombies in its monster spawner list.
That is the thing gap 210 said was
impossible: the ward's real claim — that hostiles do not spawn near
a warded horse — can finally be tested, because there is finally something
for it to stop.
Two consequences, both handled. A sealed unlit box now fills with
zombies overnight, so the glow room carries invisible light blocks at
level 1 — enough to stop spawning, still black to the eye,
and a glow is judged against the room rather than against absolute dark. And
“is the spawner producing” stops being answerable if a natural zombie
looks identical to a spawner one, so every monster spawn now logs its
reason. That distinction is load-bearing: the ward lets spawner mobs
through on purpose, so a spawner zombie beside a warded horse is expected
and a natural one is the gene failing.
§0-DB — The night loci, testable for the first time (2026-09-13, NOT looked at)
§0-AT has said since 2026-09-09 that "the night loci - behaviour, so nothing
here is confirmed by a render". Two whole loci,
night temper and
night watch, that nobody has ever seen do
anything. The reason turned out to be the dimension, not the genes:
the horse dimension had no night, because a dimension_type needs
timelines as well as a default_clock and it had only the
clock. Every night-gated gene in the mod sat inert in the one place built for
watching genes.
Fifteen stalls, one per behaviour, in two rows at the back of the
yard. Every variant gets its own, because the variants are the point —
they differ by who they are about (riders, herds, monsters, everything) and a single
pen would answer for one and leave the rest exactly as unproven as they are now. It
is a walk down two rows with /testkit night run once.
- Night temper, eight stalls: hunt and shy, each toward riders, herds, monsters and everything. The riders and everything forms are testable with nobody present but you — walk up by day, set night, walk up again. The herd forms have a cow each so they have something to be about.
- Night watch, five stalls: fixed, closing, sighted, unseen, close behind. After dark each should stand and watch rather than graze, and the five differ in what they watch.
- Dhampir and lycanthropy get a stall each — both are night-gated and both were equally unwatchable for the same reason.
- Two stalls say CANNOT FIRE HERE on the sign, and that is deliberate. The monster-targeted forms need a hostile nearby, and the only hostiles in this dimension come from the ward's spawner, which runs only with a player beside it. A stall that cannot fire is worse than no stall, so those two are labelled rather than left to look broken.
- Base alarm is now beside the spawner room, which is the
only place its
hostile_nearcondition can be true. It was deliberately kept out of the sound herd for that reason - a hundred blocks from any monster it would have been silent all night, and a blank in the log reads exactly like a broken gene. The census counts sounds by id, so the answer arrives as a number beside the ward's spawn lines. - And check the sky itself.
/testkit nightreports what the dimension reads. It said DAY after being set to night on 2026-09-13 - that is the bug that was fixed, and the same line is how you confirm it stayed fixed.
§0-DA — Two more things the night can answer for free (2026-09-13, NOT looked at)
The measuring half is built, so the marginal cost of another test is a pen or a counter. These two were picked because the thing that would answer them was already running.
- The retinue's cost. §0-BT ranked this itself: “leader of the pack is the performance one… one horse is certainly fine. A stable with several pack leaders in it is the case I have no feel for at all.” The new pen holds four leaders and sixteen cows — twenty-four mobs re-pathing on a forty-tick beat, all night. The census already prints real milliseconds per tick, and the dimension's baseline is a flat 50.0. Pass: it stays at 50.0, which would be the first time anyone could say what this gene costs. A climb, with the entity count flat, is the finding.
- How often a
spreadactually lands. Gap 208 predicts a hit rate near one in three for anything that plants, because the verb picks one block per interval with a vertical offset of −1, 0 or +1 and only 0 can work for something that builds upward. That was an inference from reading the code and a single suggestive observation (three plantings where the interval says twenty). The census now printsplaced/triedper cover. Near 33% confirms the gap; near 100% means the offset stopped mattering and it can be closed. Either way it stops being an argument.
And two ridden pens, which are a different shape from everything else here
Every other pen in the yard is watched. These two need a person in the saddle, so both horses come already saddled — a ridden test whose first step is “find a saddle” is a ridden test that gets put off.
- The lava channel, 19 blocks, two deep, dry stone at both ends. Ride in and time it. That is the whole test: gap 179 asks whether a crossing this slow is acceptable or worth the project's first mixin, and it is a judgement that needs a run long enough to be boring. Note what the pen cannot show: the horse survives lava whether or not it is fireproof (the dimension cancels horse damage) and so does the rider (creative). Both are confirmed already; this is about speed alone.
- The hydrophobic pen — CONFIRMED 2026-09-13, and it does more than its page claimed: it throws the rider and heads for an edge. The pen stays only because it costs nothing; the gene is done.
The ward pen. See §0-CW, which now says the opposite of what it said this morning — it is worth reading before the night rather than after.
§0-CZ — Dryad is nine alleles now, and intimidating pushes properly (2026-09-13, NOT looked at)
Dryad went from Dry/n to nine variants
plus the wild type. That rewrites the locus's founder table and every
genotype string that mentions it. Any horse in an old save carrying
Dry has an allele that no longer exists. Dev-only, single
tester, no saves worth keeping (hard rule 6) — but start a fresh test
world rather than wondering why an old one reads oddly.
What to check, in order
- A matched pair plants its own species and nothing else. Spawn
Oak/OakandSpru/Spruand leave them in the yard. The watch names the block, so the log answers this without anybody looking. - A mixed pair plants both, at half rate.
Oak/Brchshould leave roughly as many things per hour asOak/Oakdoes, split between the two. This is the new rule and nothing has ever exercised it. - A carrier still does nothing.
Oak/nis the control — if it plants, the recessive-to-wild-type half has broken and the whole locus is now dominant. - Dark oak makes a square.
Dark/Dark, left alone. The saplings should cluster rather than scatter, and a tree should eventually appear. This is the one most likely to be wrong, because the clustering search is new code with no test behind it — and it fails invisibly, as a pen of saplings that never become anything, which is exactly the symptom it was written to cure. - Mushrooms only appear where they survive.
Mush/Mushin daylight on grass should plant nothing at all — that is the pass, not a failure. Put one in the yard's dark spawner room, or on mycelium, and it should plant there. If mushrooms appear in the open and vanish a tick later,canSurviveis not being consulted. - Bone meal never touches a crop.
Bone/Bonebeside a wheat field is the test that matters, and the one with a design decision riding on it. It should hurry saplings and grass and leave every crop alone. - Intimidating: the number should move. The yard measures it automatically. Tonight's baseline is a median nearest-cow distance of 4.2 blocks with 63 of 64 readings inside 8. If the path-based repel works, the median should sit at 8 or more and stay there. This is the first change in the mod measured against a number collected before it was made.
The DRYAD pen counts saplings, logs and leaves; the census names the
block and the delta. So most of the list above is answerable from
grep '[watch]' in the morning rather than by standing in a pen. What
it cannot see is a mushroom that was planted and popped — for that, the
block placed event lines are the evidence, and their absence is the
pass.
§0-CY — The first night's readings (2026-09-13, read off the log)
The run started 23:07 and was still going at 02:04: 89 censuses, a flat entity count (154–155, so nothing leaked) and a flat 50.0 ms per tick throughout. The watch did the job it was built for. What follows is what it found, and two of the six pens turned out to be testing nothing — which is itself the result, and the reason the census prints every pen whether it moved or not.
Dryad — confirmed, for the first time ever
00:00:03 a sapling appeared; 00:01:09 it grew. Six oak logs and fifty-two leaves, seventy seconds apart, in a pen that had been bare grass. That is the whole gene working end to end — plant, then vanilla's own random ticks — and it has never been seen before, because until yesterday the dimension forbade the spread verb and before that the plot had the wrong floor.
But it planted three times in three hours, not twenty, and the reason
is worth knowing because it applies to every spreading gene.
GeneAbilityHandler.spread picks one random block per interval,
from a cube of radius around the horse with a vertical offset of
−1, 0 or +1, and gives up silently if that block will not convert. For a
sapling the only offset that can ever work is 0: −1 is the
grass block itself and is not air, +1 is air with air under it. So two
thirds of the dryad's attempts are thrown away on geometry, and its
effective rate is about a third of the 9 000–32 000 ticks its page
advertises. Not a bug, and worth saying out loud on the gene's page
(gap 208).
And one in six of its saplings can never grow at all.
saplingFor picks from six species by position hash, and one of them is
dark oak, which vanilla will only grow from a 2 × 2
block of saplings. A lone dark oak stands for ever: one was planted at 01:28 and was
still a sapling at 02:04, while the oak next to it had become a tree in seventy
seconds, and a third position logged ten failed growth attempts
between 01:15 and 02:01. Fixed the same day by putting the species on
the allele and clustering the dark oaks - §0-CZ, and
the gene's page.
It also plants outside its own pen. A radius does not respect a fence: saplings appeared at z 110 with the pen's back wall at z 107, so the watch box under-counts. A test-design fault rather than a gene one — the box wants to be wider than the radius.
Egg layer — the cap never fired, exactly as predicted
Ground count peaked at five against a cap of eight, sat at two or
three most of the night, and of 57 eggs removed every single one
despawned — not one was picked up or refused. That is
gap 207 confirmed by measurement rather than by
arithmetic: four layers in one six-block circle still cannot outrun vanilla's
6 000-tick despawn, so nearby_cap is decorative in any real game.
Either it wants an interval that can outpace the despawn or the verb's page should
say the despawn is doing the work.
Holy ward — no data at all, and the control caught it
Zero monster spawned lines from the yard's spawner in three
hours. BaseSpawner.serverTick begins
if (this.isNearPlayer(...)), and
requiredPlayerRange is 16 blocks. The spawner only
runs while somebody is standing next to it, which is the one thing an overnight
run guarantees nobody is doing.
The fix costs nothing and needs no code: AFK inside or beside
the spawner room. Every other pen is force-loaded and runs regardless of
where the player stands, so the spawner room is simply the best place to leave the
character. Alternatively the field is settable through the block entity's
RequiredPlayerRange NBT, but standing in the right place is free.
Worth noting what did work: §0-CW's control line — “if
the log has no monster spawned lines anywhere, stop there, because a
silent spawner and a perfect ward look identical”. Without it, three hours of
no hostile spawns beside a warded horse reads as a triumphant pass.
Intimidating — looks like a failure, and wants a person to confirm it
The gene says everything that is not a horse is held outside a radius written on the allele copy, at least eight blocks. Measured: median 4.2 blocks, upper quartile 5.4, maximum 8.0, minimum 0.6, over sixty-four readings across three hours. The cows started at three blocks and never got meaningfully further away.
It is not doing nothing — a shove is a velocity nudge of
0.35 every twenty ticks, and a cow that walks back in between beats will sit
wherever the two balance. But “pushed out and held out” is not what
this reads like. The candidates, in order: the aura is not firing at all (check
for a repel in the horse's resolved ability list, not its genotype);
the shove is too weak against pathfinding; or the pen is too small for the effect
to be legible. Do not fix it from this alone — go and
watch one for a minute first, because a velocity nudge that works and one that
does not look different in a pen and identical in a column of numbers.
Hot blooded — it thawed, it did not flood, and it stopped early
Snow 81 → 62, ice 18 → 3, water 0 → 32, all of it inside the first fifty minutes and then completely static for over two hours. Two readings out of that:
- The water more than doubled the ice's footprint — fifteen ice blocks became thirty-two water blocks, because ice melts to a source and a source flows. That is the flood behaviour, and in a flat fenced pen it found its level and stopped. It is still the thing to watch on any terrain with a slope.
- It stopped because the horses stopped moving, not because it finished. The melt radius is 2.0 and the pick is one block per four seconds, so once a pair of horses settle they clear their own little cube and nothing else is ever in reach. Sixty-two snow blocks and three ice are still standing five blocks away. Again: the gene doing exactly what it says, and a test that cannot see the whole claim.
Everything else
- No leak. Entity count flat at 154–155 for three hours, tick time flat at 50.0 ms. The thing most likely to damage a save did not happen.
- The sound rates are exactly as specified and did not drift: 24 × cat and 4 × disc per two minutes, every census.
- Read
50.0 ms/tick — BEHINDas healthy in this night's log only; see the note on §0-CX.
§0-CX — The overnight watch, and a yard that runs itself (2026-09-12, NOT looked at)
The tick-time threshold fix (BEHIND_MS) is committed and
type-checked but not in the client that ran the night of
2026-09-12: rebuilding would have overwritten the classes under a
live client. So that night's log says BEHIND, the server is not keeping
up on roughly half its census lines at exactly 50.0 ms/tick,
and 50.0 is the healthy reading - this measure is wall-clock
divided by ticks, and a server that keeps up sleeps out the rest of each tick,
so it can never read less. Only a figure clearly above 55 means anything.
The owner's brief: “I'm going to leave the game and the horse dimension running over night. Add as many time-reliant tests as possible, focusing on those that don't require direct intervention from me.” That is a different design brief from the one the yard was built to and it rules out more than it lets in — a test belongs in there now only if it starts itself, runs on a clock, and leaves something readable in the morning.
The third of those is the new part, and it did not exist.
ActionTrace logs things a person does; every overnight test
is the opposite — a sapling that appeared, snow that stopped melting, eggs
that piled up and then stopped. None of those is an event anybody fires. They are
differences between two readings, and nothing in the repo took
readings. DebugWorldWatch does.
Before walking away — four things, in this order
- Go through the hay portal. The yard is built when you enter the dimension, and so is the watch. No portal, no night.
- Run
/testkit census. It prints every watched pen to the log at once. This is the check that costs one line of chat and saves eight hours — if it answers nothing is being watched, the night will record nothing and there is no way to tell from inside the game. - Stay logged in and out of the pause menu. Singleplayer stops the server on Esc; a paused server ticks nothing at all. The yard's chunks are force-loaded, so where you stand does not matter — only that the game is running.
- Do not leave the horse dimension. Leaving tears the plot down, and the night with it.
What it writes, and how to read it in the morning
Everything is prefixed [watch], so the night is one grep:
grep '\[watch\]' neoforge-26.1.2/run/logs/latest.log. Two clocks and a
pile of event hooks:
- A scan every ten seconds counts the watched blocks and creatures in each pen and logs only what changed. This is what dates a planting to the minute with no event to hook — the dryad plants by writing the block.
- A census every two minutes prints every pen whether it moved or not, plus the dimension's entity count, whether it is day or night, and how many milliseconds the server actually spent per tick. Over 50 means it is behind, and the entity count on the same line is almost always why. A flat line in the census is evidence; a gap in the log is not.
- Event hooks for the things a delta cannot explain: every item dropped and every item removed, with its age (a despawn at 6 000 ticks and a cap refusing to drop look identical in a count and opposite in a log), creatures joining and dying, bone meal, a sapling becoming a tree, blocks placed by anything that is not a player, explosions, teleports. Gene sounds are counted rather than logged, because five horses meowing on a 300-tick timer is seven thousand lines a night.
- It throttles itself at 400 lines a minute and says how many it swallowed. The tool that finds a runaway must not be the thing that makes it worse.
What each pen should say by morning
- EGG LAYER — four of them in one pen, which is the only arrangement that can make the cap fire at all. The guard is eight of the item within six blocks; a copy's interval is 4 000–14 000 ticks and a dropped item despawns at 6 000, so one horse can essentially never reach its own cap — the floor clears itself about as fast as one horse fills it. Pass: the count climbs, sits at or below eight, and the item-gone lines show pickups rather than a column of despawns. Fail: a floor carpeted in eggs.
- DRYAD — a sapling every 9 000 to 32 000 ticks, so about a game day between plantings. Its box is six blocks tall, because the far end of this test is a grown tree and vanilla only grows one on random ticks in a loaded chunk — which is the reason the yard is force-loaded. Pass: several sapling lines overnight, and ideally a tree grew.
- HOT-BLOODED — a snow floor with a strip of ice in it. The ice is the half that matters: it melts to a water source, not to air, which is how this gene could flood something. Pass: snow falling steadily. The thing to look for: whether the water count keeps climbing after the ice is gone, which is a flood rather than a thaw.
- INTIMIDATING — six cows ringed round one horse. Measured as a distance, not a count: penned cows cannot leave, so four in the far corner and four round its feet are the same number and opposite results. The watch reports the nearest non-horse every ten seconds. Pass: it climbs within a minute and sits at eight or more all night. Fail: a figure wandering between one and six as they graze past.
- SOUND HERD — three meowing and two singers, and
the first census answered it: 24 ×
entity.cat.ambientand 4 ×music_disc.catper two minutes, which is exactly what a 300-tick and a 1 200-tick interval predict. The cooldowns do what they say. So the open question is no longer “is it working” but “is twelve meows a minute from three horses bearable”, which is a judgement, and one you can make by standing in that pen for thirty seconds.And it turned up a third sound nobody put there. 40 ×
entity.bat.ambientper two minutes — echolocate, which isFounders.EXPRESSING, so the corridor's gallery horses draw it and the hundred-and-forty of them are audibly echolocating at twenty calls a minute. That is a “feel” question for the corridor rather than a bug, and it is one nothing would ever have asked, because the noise is ambient and the mind edits it out. The census counts by sound id, which is why it is separable at all. - WARD + SPAWNER — the best of them, because it is the one with the most data. Every hostile spawn is logged with its distance to the nearest live ward, so a night is a column of hundreds of numbers (§0-CW).
- The census's own entity count is the safety net under all of it. An entity storm is the one failure here that damages a save rather than looking wrong, and a count that climbs all night is how it announces itself.
Three fixes underneath it, none of them visible
- The yard's horses are all tamed now. The kit's legend has said “the yard's horses come tamed” since the day the yard was stocked and the stocked row never was — so “breed a starburst pair in the yard” was another instruction nothing in the world could carry out.
- Leaving the dimension no longer walks the yard home.
evacuateTamedHorsestook every tamed horse in the plot back to the overworld, which with the line above would have meant two dozen of them at the portal on every exit and an empty yard on the way back in. It takes tamed and owned horses now — a horse a player tamed has an owner, and the yard's scenery does not. - Spontaneous breeding stops claiming foals that are not coming.
The post-breeding cooldown is
getAge()andcanFallInLove()cannot see it:Animal.aiStepzeroesinLoveevery tick while the age is non-zero, so a pair that had just bred read as available and were put in love again on every beat — hearts cleared the following tick, for five minutes. The owner's log of 2026-09-12 has two foals and then 212 identical PAIRED lines with nothing behind any of them. The gene was working; its account of itself was not.
§0-CO — Glow is a level, not a bit (2026-09-12, the levels are confirmed; the list below is what is left)
Gamma, geode and angler look right, and ember veins and
data rain have no falloff at all — which is what the measurements said should
happen before anybody looked: those two are hard-edged by construction (0.04 to
0.2, and soft bands times a SPECKLE), so coverage-times-level is
level-or-nothing there. The softest lit mask in the mod is gamma's
SPOTS at 1.8 and it is the one that shows the change.
So the glow level works, it is scaled by coverage, and it is invisible exactly where the geometry says it should be invisible.
And the control held: suntouched
“does indeed look the same as before”. That is the one that mattered
most, because it lights whole parts at full alpha through the glow
effect rather than through a coat layer — so it exercises the same new alpha
path with none of the new arithmetic. Unchanged there plus changed everywhere the
masks are soft is the pair of readings that says the level reached the renderer
without disturbing what was already right. §0-CO is closed.
A layer's emissive is a number now, and the mask's coverage
scales it: the old threshold at coverage 0.5 is gone, so every
soft-edged glow that used to end on a line now fades out. Fifty-two layers
across the shipped genes say "emissive": true and every one of
them is affected. The arithmetic is covered by
GlowIntensityTest; what no test here can reach is what it
looks like, because the glow only exists in a render, at night, in a
world. The creator does not draw it either — its preview is a flat sheet
with no lighting to be brighter than.
- Look at a soft-edged glow at night. The list this entry
first gave was wrong, and the owner found it in about a minute: “I
don't think ember veins has any fall off.” It does not, and it should not.
The genes were picked by whether their glow sat behind a field mask rather than a
part list, which is not the same question as whether that mask has a soft
edge. Measured, the lit layers are:
ember veins 0.04–0.2,
angler 0.12–0.18,
geode a soft
AXIStimes aWAVESat 0.09, data rain soft bands times aSPECKLE— all hard-edged by construction, and all correct to look unchanged. - The one to actually look at is gamma
(
SPOTSat softness 1.8, the softest lit mask in the mod), and the two already confirmed: lantern's bloom (CENTERLINE1.2) and tron's halo (EDGE0.55). Rime at 0.5 is a distant fourth. - Why the rest cannot show it, and it is worth knowing: a layer's
masks fold by
MULTIPLY, so the hardest mask in a layer governs its edge. Geode's glints are aWAVESat 0.09 inside anAXISat 3.0 and the product is as hard as the 0.09; data rain's flecks are soft bands times aSPECKLE. Coverage there goes 0 to 1 over almost no distance, so coverage-times-level is level-or-nothing and the change is invisible - which is the correct outcome, not a missing feature. - Is a dim glow visible at all? The intensity is the second texture's alpha over a blended pass, so a 0.2 texel is a fifth of full bright over the coat as the world lit it. In daylight that may be nothing at all. If the bottom of the range is invisible in practice, the useful range is narrower than 0–1 and the genes should say so.
- Two glows on one horse. Overlapping lit texels take the brighter of the two rather than summing, deliberately — check that a horse carrying two glowing genes does not look like it is carrying one.
- A glow pointed at the gene's dial is the new thing worth building on purpose: a gene whose glow varies per horse, bred over a few generations, so some of the line smoulders and some blazes. Nothing ships like that yet.
- The eye glows and Suntouched's parts are unchanged — they light whole regions outright at full alpha, and they are the control group. If those look different, the alpha path is wrong rather than the levels.
Owner's rule, 2026-09-12. She is the only person who can run the game, so time in it is the scarcest thing in the project - and a session that re-checks finished work spends it twice.
- Audit the test kit. Every batch in
DebugTestWorldHandler.BATCHES, against this page: a batch whose section is confirmed is deleted and the rest move up; a batch with a confirmed item in it gets that slot re-aimed. Batch 1 is always the next thing that needs a person. - Audit the horse dimension. Are the structures in it still for something open, or is one of them left over from a test that finished?
- Put the whole list in chat - numbered, in order, each step saying what a pass looks like. “Go and look at the yard” is not a test; it is a thing to work out first.
§0-CV — The pens that run themselves (2026-09-12, NOT looked at)
What is left in the yard is the tests that need time rather than attention. That is what a private dimension is actually good for. Each one's pass condition, and what the log should say, is on §0-CX above; this is the index.
Gone from the yard, by the owner's call (2026-09-12): the
spontaneous-breeding field and the pack leader's pen — “we're done
with those tests”. Verdant's three floors went the same way when they were
confirmed. One question leaves with the breeding field and is worth
recording as dropped rather than answered: whether
LOCAL_CAP actually stops an automatic breeder. The breeding is
confirmed; the cap never was, and an uncapped one is the classic way to kill a
server. Say the word and the pen comes back.
- Egg layer, four in a pen — does the accumulation guard hold, or does the floor carpet?
- Dryad, on grass — a sapling about once a game day, and a tree eventually.
- Hot blooded, on snow with a strip of ice — does it thaw, and does the water stop?
- Intimidating, with six cows — does the nearest-cow distance climb and stay up?
- The sound herd — how many plays a minute does a herd of five actually make?
- The ward's spawner — §0-CW, and the one with real numbers behind it.
§0-CW — Holy ward: the yard tests the half that is not the headline (2026-09-13, NOT looked at)
It said a night of spawn distances would show the ward working. It cannot, for two independent reasons either of which is enough (gap 210):
- The ward lets spawner mobs through on purpose.
GeneWardHandler.isNaturalgates on the spawn reason, and spawners, eggs, breeding, structures and commands all pass — because a gene that silently broke somebody's mob farm is the failure that whole design exists to avoid. The yard's zombies are mobs a working ward is supposed to ignore. - Natural spawning cannot happen in that dimension at all.
debug_pensgeneratesminecraft:the_void, and the void biome has no mob spawn entries. There is nothing there for a ward to cancel, at any light level, at any distance.
And in a real world the warding half only bites more than 24 blocks from every player, since vanilla never naturally spawns a monster closer and the ward reaches 8–16 (gap 180). So the gene's headline claim has never been tested, and cannot be tested here.
That a warded horse does not break a mob farm. The ward hooks
FinalizeSpawnEvent — a global, high-frequency event shared with
every other mod in the pack — and if its allow-list is wrong, a spawner
stops producing and nothing anywhere says why. That is the failure that damages
somebody else's world, and it is the one this pen can actually catch.
Pass: a steady stream of monster spawned lines beside
the warded horse. Fail: silence. And this is the pen that
needs you — a vanilla spawner will not run unless a player is within
16 blocks (BaseSpawner.requiredPlayerRange), which is why three hours
unattended produced nothing at all last night. AFK in the spawner
room. Everything else in the yard is force-loaded and does not care where
you stand, so that room is simply the right place to leave the character.
It needs a real world, not the yard: a dark room, a warded horse and an unwarded control room the same distance away, both more than 24 blocks from where the player stands, left overnight. The watch already logs every hostile spawn with its distance to the nearest live ward, so the apparatus exists — it is the place that does not.
§0-CS — The horse dimension's test yard (2026-09-12, NOT looked at)
Thirty blocks right of the arrival road, through a door in the corridor wall: a walled yard of signed pens. See the dimension page for the plan and what is in each one. It replaces the first pen on that side.
A pen for an answered test is the most expensive thing in this project, because it spends the one resource that cannot be bought back. So the yard is audited against this page every time the page moves, and a confirmed test's pen is deleted rather than left standing with a tick on it. Gone that way already: verdant's three floors, the pack leader's cows, and the spontaneous-breeding field.
- Look in the log first. Building it prints either test yard built and walkable or a count of holes. If it says the second thing, nothing below is worth doing until that is fixed.
- Walk it. Out of the portal, turn right, follow the path. No gaps underfoot, no wall to squeeze past where the doorway was cut, and the yard's own wall should close all the way round with no view of the void. Seven signed pens: egg layer and the ward's spawner room at the near end, the sound herd and the cows in the middle, starburst and the F8 herd and the glow room behind them, the dryad and the thaw along the back.
- Every horse in it is tamed — new, and the thing that makes the starburst breeding test possible at all.
- Then leave it running, which is what the rest of it is for: §0-CX.
- Then leave and come back. Re-entering builds a fresh plot; the yard should be there again, with its pens stocked and nothing left over from last time. The plot box covers the yard, and the forced chunks are released on the way out — a dimension still ticking a yard that is nobody's would be a bug this session introduced rather than found.
§0-CR — The kit breeds, and Make egg works (2026-09-12, NOT looked at)
The kit only ever handed out mares, and
HorseBreedingHandler cancels same-sex pairings - so batch 3's
spontaneous-breeding test ("spawn FOUR in a wide fenced field, come back and
COUNT") had never once been runnable, and the starburst breeding slot written the
same morning inherited the fault. Every batch that breeds now carries both sexes,
and that is written into the class as a rule rather than left to the next author.
"Make egg" sent no packet at all. The right-hand column's seven
full-width rows plus the three pinned below them do not fit a 270px window (1080p
at GUI scale 4); the groups overlapped, the top one is registered first, and so
"Clear genes" sat on top of "Make egg" and took its clicks. Since
reset() on an untouched horse changes nothing you can see, it read as
a dead button. The toggle and Clear now share a row (six rows, not seven), and the
screen warns in the log if the two groups ever collide again
rather than silently eating clicks.
- Press Make egg in the custom spawn screen at your usual GUI scale. It should say wrote this horse into a preset spawn egg and the egg should be in your inventory - note it goes to the first free slot, so with a full hotbar it lands in the backpack rather than in front of you.
- Then try it at GUI scale 4 and at scale 2, and look for [Custom Horse] the right column does not fit this window in the log. At some small size it will appear - that is the honest limit, and the fix for it is a scrolling column rather than more pairing.
- Check "Clear" still clears. It is half-width and renamed from "Clear genes"; the tooltip carries the full sentence.
- The horse designer was mirrored (hard rule 5) - open the designer and confirm its right column matches, since it copies these constants by value.
- Breed the starburst pair in the yard with batch 1's golden carrots. The foal's emblem should sit near its parents' rather than re-rolling. This is the one test in the yard that still wants hands, and it is finally possible: the yard's horses are tamed now, and vanilla will not breed an untamed one.
§0-CQ — F8's highlight no longer crashes the server (2026-09-12, NOT looked at)
The horse highlight took every nearby horse off the herd-lead scoreboard team,
including the ones never on it, and
Scoreboard.removePlayerFromTeam throws for those. It hid as
“F8 only turns on” for four minutes and then killed the integrated
server from the auto-off tick. This is not dev-only: the binding
is registered outside the production gate because the testers asked for it, so a
real jar can hit it.
- Press F8 twice. Second press must say Horse highlight OFF and the outlines must go. That is the half that never worked.
- Then leave it on for four minutes near a herd with a lead in it. It should say Horse highlight timed out and stay up. That is the path that crashed.
- Check a herd lead's name goes back to white when the highlight goes off - it is red only while on the team, and the removal is now conditional, so a lead that somehow ends up on another team is left alone rather than throwing.
- Nothing else should be able to take the world down either. The tick now switches the overlay off and says so instead of propagating. If you ever see Horse highlight hit an error and switched itself off, that guard did its job and there is a stack trace in the log worth reading.
§0-CP — Starburst scales, Lantern and Tron burn (2026-09-12, the scaling is confirmed)
These are what make §0-CN and §0-CO real. All three changed their own coat golden rows and nothing else's, so the blast radius is exactly these loci.
This is test kit batch 1. runClient, press
Spawn Test Horse World, and the hotbar you are handed on login is this
list: six eggs, golden carrots to breed them and a clock, because half of it is a
night test. /testkit offers /time set midnight beside
the batch list. The world is the same plains every time — the seed is fixed
(DebugTitleScreenButton.TEST_WORLD_SEED) so that what differs between
two screenshots is the mod and not the weather.
“The starburst does indeed look like a smooth variety of sizes.” That
was the open question and the one nothing in the repo could answer: a
pointsMin floor of 45% with a uniform dial over 0.45–1.0 gives a
continuum rather than two sizes with a gap, so the floor does not
want raising and the morph is doing what it was built to do on a real horse.
It is the first evidence that a drawn marking that erases down is worth having at all, which is the thing the whole feature rested on. What is still unseen below is everything else about these three genes.
- Its shards were retuned on the way past (spacing 3.4 → 2.8, chance 0.4 → 0.5) because they were already a coin flip — measured over twenty horses, the layer painted nothing on five of them. Look at a big emblem and check the shards read as a shattered star rather than as speckle.
- Lantern's bloom is lit now, at 22%, with the mane carry at 18% and the core on the dial (0.35–1.0). Partly confirmed 2026-09-12: “it does seem like lantern has different light levels”, which is the dial reaching the renderer — a knob-driven glow is a level per horse and it is visibly one. What that does not yet say is whether the light FALLS OFF. One horse, at night, up close: the bloom either side of the line should fade out over its own soft mask rather than ending on a line at the core's edge. That is the half of the change that touches every glowing gene in the game, and it is a different observation from horse-to-horse variation.
- Tron's haloes are lit at 25% and its tubes are on the dial (0.4–1.0). Confirmed 2026-09-12: “Tron does indeed have a glowing diffuse painted along the body for both forms, though more noticeable in the gradient form.” A soft-masked layer carrying light is the whole of what the threshold removal bought, so this is the first sighting of it working on a horse.
- Why the gradient reads stronger — and it is not the level.
Both haloes are
"emissive": 0.25and both paint atstrength 34; the only difference is that the gradient's op is aRAMPsweeping hue 300° along the body where the solid's is one flat hue. A glow has no colour of its own - the emissive texture is written with whatever colour the coat ended up being at that texel - so two layers lit to exactly the same level read differently depending on what they painted. Worth knowing before somebody “fixes” a dim-looking glow by raising its level when the answer is its colour. - Still unseen: the
bothegg's overlap. That horse carries solid and gradient tubes as separate layers on the same edges, and where they crossCoatOverlaytakes the brighter rather than summing. Blown out to flat white there means the max-not-sum rule is broken. Note the two haloes' paint does sum, so that horse's wash is more colourful than either form alone - that part is expected. - Is a flat halo beside a varying core right? The haloes are constants because the format has no arithmetic - "a quarter of the core" cannot be written - so a dim Lantern has a proportionally brighter bloom than a bright one. It should read as the light guttering rather than as the halo taking over; if it does not, the answer is probably a second knob rather than a wider floor.
§0-CN — The dial, the minimal shape, and the slider (2026-09-12, NOT looked at)
A knob may be marked "dial": true, and a PATH may carry
pointsMin — the same shape at the gene's weakest, morphed point
to point as the dial falls, so a drawn marking gets smaller rather than
fainter (the format). Fifteen headless
checks drive the canvas and the slider, and an answer table in the parity fixtures
compares the morph itself in both engines. What no script can say is
whether it is worth drawing with — and three genes carry one now, so
there is something to look at: §0-CP.
- Draw a marking and erase it down. In
the creator: add a
PATH, draw a shape, add a range knob and tick dial, then press Minimal on the canvas. It seeds by shrinking what you drew toward its own centre. Drag the slider from 0% to 100% and watch the horse. The question is whether the seeded shrink is a useful starting point or whether it always wants redrawing. - Is the dashed ghost readable? The shape you are not editing is drawn behind as a dashed outline with small dots at its points, on the same 310px canvas that §9.2 already calls dense. Two shapes, one surface — if it is a tangle, the answer is probably a dimmer ghost rather than a second canvas.
- Does the twinning ever get in the way? Adding, inserting or deleting a point on either shape does it to both, because the loader refuses a mismatched pair. That is right for keeping a file loadable and it means you cannot give the minimal shape fewer corners — worth knowing if you hit it while drawing something real.
- Put one in a gene and breed it. The whole point is a population
where the marking varies in size: put a
pointsMinon a gene, spawn a dozen carriers, and see whether the spread reads as natural variation or as two distinct markings with a gap in the middle. - The dial is stored, inherited and drifts like any other knob, so a foal should look close to its parents and not identical. That is the part only a breeding session can answer.
§0-CM — A third-party mod can add a gene (2026-09-11, NOT looked at)
RegisterHorseGenesEvent compiles against 26.1.2 and its firing
point is read off the loader's own ModLoader.constructMods
(fancymodloader 11.0.15): every mod is constructed, each gets
FMLConstructModEvent, and only then is the deferred work queue
drained on the sync executor — so a task enqueued from that handler runs
exactly once, after the last mod exists and before any registry event.
That reasoning has never been run. Everything on the
common/ side of it is covered by GeneApiTest; the
event itself needs a second mod, and there is not one.
The cheap check, with no second mod at all: boot the game or a
server and look for the line
[genes] 0 gene(s) registered by other mods; the registry is frozen at N
segments. If it appears, the event fired and the freeze happened at the
right moment; if it never appears, the enqueued task never ran and the reasoning
above is wrong. N must equal the segment count
ModGeneSpecs logs two lines earlier.
- The real check is a throwaway second mod — a
build.gradle, a@Modclass, one listener, and a gene extendingAbstractNaturalGene. What it proves that nothing else can: the listener is called at all, the gene lands in the sorted order rather than after the built-ins, and a wild horse really carries it. - Then remove that mod and load the same world. It should refuse the saved horses, not crash — a gene's segment leaving the code is the same event as a drop-in gene being deleted, which is expected and handled. This is the failure mode a modder will hit first, so it is worth knowing which of the two it is.
- Register a gene with a bad key (no dot, or capitals) and confirm the refusal names the mod and the key rather than appearing as a missing locus later.
- The freeze should be unreachable in normal play. Nothing in
the mod registers a gene after startup; if the frozen-registry
IllegalStateExceptionever shows up in a log, something is callingGenes.registerfrom the wrong place and the message says so.
§0-CL — The PATH drawing canvas (2026-09-11, NOT looked at)
Open the gene creator, add a
PATH mask (or load Prismatic, which carries two), and
the points parameter is a horse you can draw on. Forty-one checks of
it run in headless Chrome — clicks land where aimed, a drag moves one handle
and no other, the midpoint marker inserts in order, right-click deletes, the
textarea and the canvas agree in both directions, and all three planes map their
two axes at one scale — so what is unlooked-at is not whether it
works but whether it is pleasant, which no script can
answer.
- Is the silhouette readable as a horse? It is the model's own boxes — each part's body-space AABB — because that is exactly the region a point can land on. Blocky is honest here, but if it reads as a pile of rectangles rather than a horse, that is worth knowing.
- Draw something real. The shapes this was built for are the ones
that cannot be described in words — a peacock feather, a laced tobiano edge.
Try one end to end: click a dozen points, tick
curve, tickfill, and watch the horse beside it. - Is 310px wide enough? It sits in the right-hand column, which §9.2 already calls dense. If the answer is no, the fix is a bigger surface somewhere, not a different control.
- Does the snap help or fight you? Handles land on a 0.01 grid of the body box (about 0.4 of a body unit) so the numbers that reach the file are readable. If a shape needs finer placement than that, say so — the grid is one constant.
- The
topandfrontplanes are letterboxed — deliberately, because both axes are drawn at one scale and those planes are long and thin. Check the strip is still big enough to draw a girth band in. - Switch the preview to a foal. The silhouette should become the
baby mesh, and the shape should stay where it is in
bodyspace.
§0-CK — Feeding says when it did nothing, and a favourite is never refused (2026-09-11, NOT looked at in game)
Investigated and the locus does express - roughly one horse in eight is on a
special diet, and feralOnly means breed horses can carry it too, so
it is not that they are absent. What was missing is feedback:
feeding a horse that is already on full health and at max bond (or capped for the
day) spends the item and gives it nothing, silently. Same for the favourite. That
is indistinguishable from a gene that does nothing, which is how it was read.
- Feed a hurt or under-bonded horse its food - no message. The message is only for the case where both halves declined, because either one alone is a real effect worth not talking over.
- Feed a full-health, max-bond horse - it should still eat it, and the action bar should say “<name> eats it happily, but did not seem to need it.” Confirm the food is consumed: it was never the refusing that was wrong.
- The daily bond cap counts as declining. A horse well short of max bond that has had its 15 for the day should also produce the message, which is the subtler half and the one most likely to confuse.
- A foal on a special diet can be fed its favourite. This is the case that genuinely could not be done before - the preference handler skips babies, and the diet handler then refused them. Try a carnivore foal with an apple favourite.
- Sugar and cocoa-bean favourites work. Neither is an edible item, so neither used to pass the diet handler's feed-attempt test at all.
- A special-diet horse still refuses ordinary food it does not eat, with the existing smoke and message. The favourite is the override, not a free pass for everything.
§0-CJ — A hay portal every 25 pens in the corridor (2026-09-11, NOT looked at in game)
Every 25th segment is a break with a portal home instead of a pair of pens — 41 of them, one every 175 blocks. Written up on the horse dimension. What to look at:
- Walk in and count. Twenty-five pens down one side, then an open stretch with a hay portal set back off the north side. The sign on the road should say how many pens you have passed.
- Step through one. It should put you back where you came in from,
exactly as the entrance portal does, and bring your tamed horses with you. This is
the part most likely to be wrong: it relies on
plotContainingresolving the plot from the portal's X, which is true by construction but has never been exercised anywhere but the entrance. - You should not be able to fall through it by accident. It is set back three blocks off the road edge on purpose - confirm that walking the corridor normally does not clip its edge.
- The numbering has no holes. The pens either side of a break should read …49, 50, 51 with the break between 49 and 50, not a jump to 53.
- The last pens still exist. The corridor was lengthened so the breaks are extra segments rather than pens taken away - walking to the far end should still find pen 2,000 and the end cap behind it.
- The floor and outer walls are unbroken across a break. The pens are
skipped but
buildCorridorstill runs, so there should be no gap to the void where a pen would have been.
§0-CI — Gene and allele pickers on My horses (2026-09-11, NOT looked at in game)
The browser's filter language has understood gene:SB1 since it was
written; what it has never had is a way to find out that SB1 is
something you own. Two buttons beside the filter box now list only what is in
your roster - common/horse/RosterGenetics - and picking an allele
writes the term into the box rather than doing anything new, so the filter language
stays the one thing that does the work.
- The lists are your horses, not the registry. This is the whole
point and the easiest thing to get wrong: every horse carries every gene, so a
naive list is two hundred entries of wild type. Gene... should
show only loci somebody actually carries a variant of, and Allele...
only the alleles actually present. A player with one splash horse should see
SW1and none of the other splash alleles. - Carriers count. A heterozygote should put its hidden allele in the list - finding what is hidden is the reason to look.
- Pick a gene, then an allele, and the second list should be that gene's alleles only. Any gene at the top of the first list undoes the narrowing.
- Picking a second allele replaces the first rather than ANDing two
gene:terms - somebody clicking again is changing their mind. Twogene:terms typed by hand still AND, which is a legitimate query. - A click anywhere dismisses the menu and is spent, rather than falling through to the table underneath.
- The wheel scrolls a long list. A big stable will overflow twelve rows.
- Sell or lose the last horse carrying a gene and it should drop out of the list on the next refresh, taking the narrowing with it.
The lists are built from the same client-side roster the tab filters over, which is capped (gap 76). So they describe the horses the tab can see, not necessarily every horse the player owns - and on a big stable a gene held only by a horse past the cap will not be offered. The honest fix is the same owned-horse index gap 76 wants; until then this is one more consumer of the cap and one more reason to build it.
§0-CH — Horses come to food, and run for a favourite (2026-09-11, NOT looked at in game)
server/FoodTemptGoal, written up on
horse care. Two speeds, and the gap between
them is the feature. What to look at:
- The amble is an amble. Hold wheat near a herd: they should take an interest and wander over, and you should be able to walk away from them without effort. If it reads as a pull rather than a drift, the walk speed is too high.
- The run is unmistakable. Spawn a horse with a known favourite
(
horsegenetics.food_preference=Car/Caris in the test kit already) and hold that item from across a paddock. It should notice from roughly twice as far and come at a gallop. If the two speeds are not obviously different, the whole feature has failed - the contrast is the only thing that makes the preference locus discoverable without already knowing the answer. - It stops short. Two and a half blocks, not shoving into you.
- Lowering your hand stops it mid-walk, rather than letting the horse finish its approach.
- It yields to crouch-taming. Crouch at an untamed horse holding food: the taming approach should run, not this. They share a priority and the taming goal is added first, which is what breaks the tie - worth confirming, because it is a behaviour that depends on insertion order rather than on anything declared.
- A carnivore ignores a carrot but runs at its favourite, if its favourite is something its diet forbids. That is the preference-beats-diet rule, and this is a second place it has to hold.
- Ridden, leashed and led horses ignore food entirely.
- Performance: stand in a large herd holding food and watch for a tick cost. The goal caches the genome parse, but that cache is the only thing between this and sixty full genome parses a tick.
§0-CG — Confirmed by playtesters (2026-09-11)
- Bareback steering at a high bond works. This is the one worth
noting twice: it was still listed on the roadmap as unbuilt (“riding
without a saddle gives no control today”) while
server/BarebackSteeringHandlerhad been shipping it all along. Written up now on horse care. - A horse can be ridden through water — wanted, not a bug.
Vanilla swims a ridden horse; the
water_averseability is what adds ejection, so a plain horse swimming is correct. - Breaking the equine research shelf drops what is inside it.
- Setting a barn name works, and so does clearing one — the first report said it could not be erased, and it could; it takes a beat to refresh. That refresh lag is the only thing left here: the client's cached record updates a tick late, which is cosmetic but reads as a failure.
- Destroying a horse-dimension portal stops its animations.
A tester saw entities near a horse in the horse dimension outlined by the
glowing status effect, while not riding it. MobEffects.GLOWING is
applied in exactly one place in the mod —
server/DebugHighlightHandler, the F8 toggle — which lights every
horse within 96 blocks, and the horse dimension is wall-to-wall pens. So the first
thing to check is whether pressing F8 again stops it.
If she is on a released jar, that does not fit: F8 was dev-only until 2026-09-11, so a real build could not reach it. Establish which jar before looking further. The toggle now times out after four minutes and says how to stop itself, which is hardening rather than a fix.
§0-CF — A GOO mask, and the drips rebuilt on it (2026-09-11, NOT looked at in game)
Owner's report on the first look at the drips: ooze drip “looks like triangles” and needed to be “more irregular and curved”, and both drips left “weird gaps on the top of the horse”. Rendered side-on and from above at several seeds; parity green, and watched go red. Design: the mask table.
- Ooze drip is a different marking now. A band poured along the topline whose edge sags into separate drips - each its own length, some cells empty, a heavy bead at every tip, and a concave fillet where it leaves the band. Spawn several: no two horses should carry the same run of drips, and none should read as a row of triangles. The dark lip should follow every drip all the way round.
- The bare stripes along the back are gone.
WAVESdisplaces the whole band, so rainbow drip's far edge dipped to 0.85 of the barrel at every trough and left a brown stripe on top, once per wavelength; ooze drip had the same fault. Look along the spine of both, and of anything else banded across a part. - The
GOOmask itself is new engine code - a distance field rather than a displaced line (SpecPainter, mirrored in the creator'sspec-engine.js). Nothing else uses it yet. In the gene creator, a layer using it should preview the same shape the game draws; that is what parity checks, with the caveat in gap 194.
§0-CE — The breeds and size test batches: confirmed (2026-09-11)
Owner-confirmed and removed from §0-CA / §0-CB / §0-CC, kept here for
the session log: the custom egg's Breed list starts at Feral Mixed and carries drop-in
breeds; the gene hover picture on the custom egg; a drop-in breed registers, fills its
Breeds row and shows its About text; its herds spawn wild in the biome it names (15
kit_forest_paint herd founders logged in a dark forest - the
breed_herds biome modifier works); a drop-in gene loads and draws; a switched-off
Morgan keeps its label and entry; a moved Friesian's entry gives the new biome. The log
confirmed the broken-gene breed loads with a warning and the duplicate Friesian is
refused.
Then, from the log of the dark-forest trip and the size batch: Friesian herds found
in the dark forest (the moved biome); kit_night_cremello herds founded only after
nightfall (9 after /time set night, none before); no Morgan egg in the creative
tab; a Shire towers and a Falabella stands below the waist; each size founder carries the
number of copies its band says; and two Small/n Connemaras threw all three
kinds of foal - Small/Small (0.73x, 0.84x), Small/n (0.88x) and an
ordinary-sized n/n at 1.00x.
Fixed and confirmed the same day: the debug stick now fires the tame event
(it called tameWithName bare, so a stick-tamed horse never filled its Breeds
row). New: every breed founder the server rolls - egg, wild herd, cowboy,
stable - logs a [breed-health] line of its health genes against its sheet, and
WARN ... NOT ON ITS SHEET for any disorder or magical gene the sheet does not
list. Twenty-four Quarter Horses and twenty-five Thoroughbreds logged no warning; three
Quarter Horses carried HYPP, and none carried PSSM1 or HERDA (listed, rare). “Health
genes” is the breed book's rule (HealthContribution), so leopard complex,
splash white and grey appear beside the true disorders.
§0-CD — Vanilla's village POI tag loads again (2026-09-11, NOT looked at in game)
data/minecraft/tags/point_of_interest_type/village.json had named
horsegenetics:cowboy_hitch since the hitch stopped being a POI (2026-09-07), and
a tag with one missing entry fails whole: every boot logged Couldn't load tag
minecraft:village, which takes vanilla's own village POIs with it. The entry is gone
and a dedicated server boots without the error. Unseen: what the missing
tag had broken - vanilla uses it to decide what counts as a village (raids, cats, golem
spawning). Nothing to do but notice if a village behaves oddly now, in either direction.
§0-CC — 0.5.000: the settings folder and breed-spawning.toml (2026-09-11, NOT looked at in a client)
A dedicated server was booted on it twice: run/phc/ got server.toml
and breed-spawning.toml, and an edit to the latter was re-read live (the log line
[breeds] spawn settings read from ../phc/breed-spawning.toml changed to
“shipped breeds OFF ... Feral Mixed OFF”). The logic is covered by
BreedSpawnSettingsTest. No horse has been seen to spawn or not spawn
under it. Design: breeds.
- The folder. After one launch,
.minecraft/phc/(for the dev run,neoforge-26.1.2/run/phc/) holdsgenes/,breeds/,client.toml,server.tomlandbreed-spawning.toml, andconfig/gets nothing of this mod's (a drop-in gene inphc/genes/is owner-confirmed). Mods → Horse Genetics → Config should still open all three. - Only my breeds. Set
shipped_breeds_enabled = falseandferal_mixed.enabled = false, drop in one breed that lives inminecraft:dark_forest, and restart. Explore new chunks: plains and savanna should have no horses at all, dark forests should have herds of that breed and nothing else. Withdebug.announceon, a refused lone horse logs[Breeds] wild horse at ... not spawned. - Switched off, but still a breed. Owner-confirmed but for one place: the cowboy should never have a switched-off breed (the dev run has the Morgan off) in his string.
- Feral Mixed weight.
feral_mixed.herd_weight = 100: most new herds in horse biomes should be Feral Mixed. - An old world. Open a 0.4.1 world on this jar. It should load; any
horse that carried Cleave's retired alleles logs
[genes] a saved horse carried 'horsegenetics.cleave=...'and comes back without the marking (gap 193).
§0-CB — Breeds are exactly their sheets; the breed designer's second pass (2026-09-11, NOT looked at in game)
The designer was driven in a headless browser again: all sixteen steps render, the eye strip follows champagne and a white pattern, the colour search locks a hue, a range slider lands in the file, the biome checklist and a modded id land in the file, and the last step's button exports. The breed tests are green. Nothing below has been in the game. Design: where magic comes from, the format.
In the game
- No stray magic on a breed. Find a few wild herds of natural breeds (or roll founders from the spawn egg with a breed picked, and hit Randomize a dozen times): no magical coat, particle or ability the breed does not list. A vanilla-spawned horse (Feral Mixed) still can carry one - that is now the only place random magic comes from.
- The jar no longer carries the wiki tool classes or the example
genes. Nothing in the game used them; if anything in the log says a
*Toolclass is missing, that assumption was wrong.
In the breed designer (the browser)
- Walk a breed through all sixteen steps and note anything confusing. The last step's button is Export breed.
- Eyes: brown and white from the start; click swatches. Add champagne or a white pattern (KIT, splash) on the earlier steps and the strip at the top of the eye step should show amber or blue eyes on some founders, naming the gene. With two iris colours ticked and “same in both eyes”, some founders have one of each - the two eyes are separate loci and a breed file draws each on its own.
- Colour search (markings, abilities, eyes): type “orange” or a hex code; only genes whose numbers can be a colour are listed; “add in this colour” names the gene and locks it.
- How it varies under every chosen gene: wild, within a range, or the same on every horse. Watch the preview while moving a range - it should stay inside it.
§0-CA — Drop-in breeds, the new breed designer, size by zygosity, hover pictures (2026-09-10, NOT looked at in game)
The designer itself was driven in a headless browser - every step renders, the preview and herd roll, a random pick of markings lands in the file, export names an unnamed breed, the Friesian imports, a phone-width window does not scroll sideways. Nothing below has been in the game. Design: the format, breeds.
The drop-in folder - the thing a player with only the jar needs
- Start the game once and look in
.minecraft/phc/breeds/(the instance folder for any launcher but vanilla's). It should exist, with a README. The oldconfig/horsegenetics/breeds/is no longer read. - H menu → Breeds → Open breeds folder (top right of the
breed pane). The OS file browser should open on that folder. Unverified: that
Util.getPlatform().openPathbehaves on this machine as it does for the resource-pack screen.
The gene hover picture - three places
- Custom spawn egg: the picture is owner-confirmed. Still unseen: a gene with no picture (the eye loci, the health genes) should show text only, not a purple-and-black square.
- Horse designer: the same, on the canvas (seen in a headless browser).
- Breed designer: any underlined gene name.
The breed designer
- The left pane is always the options, the right always the horse; Chosen so far lists every step and jumps back to any.
- Reroll example founder (top right of the horse) should only ever show traits you picked - and so should the six founders under it.
- Magical markings filters are measured facts
(
marking-facts.json): check a few against your eye. “Covers at most 5%” should be small marks; “white only” should be white; “Reaches: Tail, and nowhere else” should be tail genes. - Refresh the page mid-breed - it should come back where you left it (browser storage, per browser). Export is still the only real save.
§0-BZ — Twenty-four genes out of the evening intake (2026-09-10, NOT looked at in game)
Where to look: /testkit 1 and 2
in the test world - one preset egg per new gene, homozygous for the form its icon shows,
plus three other forms (nightbell foxglove, black barred wing, coloured rainbow drip). Every gene was rendered
side-on in every form before shipping; none has been on a real horse, in real light, or
with other markings on top of it.
- The rebuilt-disjoint marks - corolla, agate eye, barred wing, uraniid,
trillium and foxglove are owner-confirmed (2026-09-11), and so are that look's three
follow-ups: taper flame widened 2.6× reads as a flame; the six SVG barrel
drawings now sit wherever their
posUknob puts them, shoulder to hip; the black barred wing and nightbell foxglove show on a palomino. Left: ooze drip (below). - The two drips should hang down from the spine. Both arrived with their wave running sideways and were turned. If a drip points at the tail, the fix did not take.
- Contour cells was rebuilt, not tuned — nested polygon outlines inside one or two dark patches, where it arrived as circles that almost never appeared. It has no icon: the icon's horse is one of the roughly one in forty whose patch misses the barrel (gap 181). Several eggs may be needed to see it; check the far flank too.
- Gilded crackle should read as pale plates with gold seams. It arrived inside out — a gold haunch with pale islands — and its seam was halved. Holo flake should show separate glinting flakes on the crest; they were single texels before.
- The seven barrel drawings are small — a portrait drawing fitted to the barrel's height is a few dozen texels, and tribal claw's three strokes are hairlines. That is how they were designed; whether they read at a distance is the question. Their SVG paths were simplified to fit the point ceiling (at most 0.41% of any drawing moved, measured), so a jagged edge on candelabra would be that.
- Priorities were reassigned for all but holo flake, to put each in the family band that describes it. Two new genes on one horse should now layer the way the coverage rule intends: smaller marks over bigger ones. Rime and maelstrom are the nearest pair in the whole mod; check they look like different things side by side.
§0-BY — The third 2026-09-10 play session's fixes (NOT looked at in game)
Owner-confirmed in that session and removed from this page: the research shelf stores papers; the spawner fires on every meal with no cap; My horses shows hands; the stall ticket lands a horse properly (as a basis - still to be pushed on); the Breeds tab; molten hooves' prints render.
The kit still carries this list in its bottom two rows - four molten hooves eggs, a sheep spawner, holding pen signs and tickets, the potion mare and stallion, and the shelf and stall gear. The potion foal and the bucket were dropped for room; build them from the custom egg and creative inventory.
- The research shelf copies like a furnace. Pick a gene on Copy, put books in, close the screen and walk away: copies must keep arriving, one per book, stacking in the result slot. It used to stop the moment you clicked off, because the copy lived on the screen. Also: the title and "Inventory" labels sit in the window again (they were drawn offset twice), and the shelf opens on whichever tab you used last.
- Molten hooves has four alleles. White (
MltW) is dominant - one copy glows white. Black (MltB), one colour (MltC) and multicolour (MltM) are recessive and show only as their own homozygotes;MltB/MltCshows nothing. Check black does not glow at night, and that a colour horse and a multicolour one really differ. - A spawner's mobs are all one colour now - the allele copy's own number picks which of the mob's variants it makes (a sheep's dye, a cow's, a cat's, a frog's). Feed the sheep spawner several times: every sheep the same colour. A different spawner horse should make a different colour (usually). It was promised on the gene page and never implemented.
- The holding pen. Hang a holding pen sign on a pen's wall (it measures the room like a stall sign and flashes its outline), then right-click any horse you own with a holding pen ticket - it should arrive in the pen, dead centre. One pen per player: a second sign moves it; breaking the sign releases it. Works across worlds. Refusals to check: an untamed horse, no pen yet, a pen with no room.
- A hurt mare refuses to be milked, and says so - potion milk with a bottle and plain milk with a bucket alike: "She's hurt, and won't give ... until she's healed." Before, potion milk ignored health, and plain milk silently did nothing.
- Breed plates carry no stray magic. The Breeds tab's horse is a real founder roll, and no founder carries a magical gene its breed does not name (§0-CB). None of the 49 should show a magical coat.
- Crossbred horses never fill a Breeds row - only pure-breds do. That is how it already worked; it is now the rule, owner's call.
§0-BX — The second 2026-09-10 play session's fixes (partly confirmed)
- Stall landing: try the awkward ones - an L-shape, a stall narrower than the horse (it should still land in the middle), a full stall of hay (the ticket must refuse and not be used up). And the size message should report the real height.
- Milking a stallion with a bottle should make him rear, kick you, and say so; a foal should say it has nothing to give.
- Out of creative, taming a breed horse by hand should fill in its Breeds row and tick "tame a mare / stallion".
- Holy ward, and how to see it. With
debug.announceon, a refused spawn says so in chat (purple, at most every ten seconds). Stand at least 24 blocks from the horse - the game never spawns a monster within 24 blocks of a player. Spawn eggs beside a warding horse are owner-confirmed to still work. - Breaking a shelf full of papers must drop every one - and now its books and finished copies too.
- The chat is quiet when horses load - the
[coat]line goes to the log only, except for a coat that came out bare white.
§0-BW — The first 2026-09-10 play session's fixes (NOT looked at in game)
- On-move effects under a rider. Every
on_moveeffect was silent on a ridden horse, because the server’s copy of a player-steered horse has zero velocity; “moving” is now measured by position between ticks. Check a particle-locus trail while riding. Molten hooves has its own entry, §0-BS. - What a spawned zombie is holding — the second
finalizeSpawnthat could re-roll its gear is gone. - Every long timed effect now survives a reload. Timed beats counted
on
tickCount, which restarts whenever a horse loads, so anything slower than a few minutes almost never fired. The worst case was dryad (a sapling every 9 000 to 32 000 ticks). They now count on the world’s saved game time. Look for: a dryad horse left near you for a real half-hour should have planted something. - The breed sheet still prints decimal hands
(
15.5-17.0 hands) where the horse now shows15.2 hh. Worth deciding whether it should switch.
§0-BV — A search box on both gene editors (2026-09-10, spawn egg confirmed)
- Is half the row enough for the family menu? Long family names now truncate on the button face. The dropdown still shows them whole.
- The browser twin (horse designer):
the same box, drawn on the canvas. Check that typing
w,a,sordinto it does not also walk the horse, that Esc clears it, and that clicking anywhere else lets go of it.
§0-BU — Thirteen eye loci (2026-09-10, owner-confirmed on sight)
The owner looked at the eye loci and confirmed them all: placement, sectors, glows, the third eye. What looking cannot settle is left:
- Chaos. Two chaos-eyed horses should not match, and one horse should regenerate the same colour every time you reload.
- A splashed white horse should still have two blue eyes usually, one
blue eye sometimes, and a wedge rarely — and the genotype screen should now
show it carrying
MBl/MBl. A cremello should be light blue, a tiger-eye horse gold, a champagne one of gold / brown / green. - Breeding. A blue-eyed splash bred to a plain horse should throw blue-eyed carriers, and blue eyes should reappear a generation later on foals with no splash at all. That is the design working, not a bug.
§0-BT — Twenty-seven behaviour genes, none of them ever seen (2026-09-10, NOT looked at in game)
The whole behaviour family — §12.2's batch — is built, registered and documented, and not one of these twenty-seven genes has been watched happening to a horse. This is by some distance the largest block of unverified behaviour the mod has ever carried, and it is behaviour rather than coat: a gene that paints wrongly is obvious in a render, and a gene that acts wrongly is only obvious in play.
What is proven, by measurement rather than assertion: none of them paints. All 1056 rows of the coat pipeline golden kept their rendered-byte hashes, and all 206 new rows in the bake golden carry the same "paints nothing" hash as sex and diet. Creator parity is green at 7031 checks.
The rest of this entry is a checklist. This part is a confession. Twenty-seven genes went in without one of them being watched, several touch systems that are shared with the whole world rather than with one horse, and the list below is the honest ranking of what could go wrong badly rather than visibly. If play time is limited, spend it here.
Worst case first: things that damage a save rather than look wrong
-
Spontaneous breeding is the only gene here that can ruin a world while nobody is looking. Everything else fails in front of you. This one runs on a 600-tick beat whether or not a player is nearby, and if the local cap does not hold, the failure is an entity storm discovered hours later in a save that is already damaged.
The cap counts horses within eight blocks and refuses above six, so a single pasture should settle and stay. What I am not sure about is a large field: the count is per-horse and local, so two clusters twenty blocks apart are two separate caps, and a big paddock could hold several. That is probably fine and might not be. Test it by leaving it alone - four expressing horses, a wide fenced field, walk away for several in-game days, come back and count. This is the one to do first and the one where "it looked fine for ten minutes" proves nothing.
-
Holy ward can break somebody's mob farm without erroring. It hooks
FinalizeSpawnEvent, which is a global, high-frequency event shared with every other mod in the pack. It is meant to cancel natural spawns only, by an allow-list of four spawn reasons.If that allow-list is wrong - or if another mod uses a reason I did not anticipate - a spawner stops producing and nothing anywhere says why. Stand a warding horse beside a working spawner farm and confirm the farm keeps producing. Then check a spawn egg, and a breeding pen.
One bug in this was already found and fixed before shipping: the ward did not record which dimension the horse was in, so a horse warding in the Nether would have suppressed Overworld spawns at the same coordinates. That class of mistake is exactly what worries me about this gene - it is invisible from the player's side, and the only symptom is that monsters stopped appearing somewhere they should.
-
Spawner is owner-confirmed, and now fires on feeding, two per meal with no cap, only when the horse actually ate (§0-BX). It still has to spawn through the normal path so other mods' protections fire. Rider immunity (fireproof, bird boned) is owner-confirmed, dismount included; ocean-born is the one still unplayed.
Things I expect to be subtly wrong rather than dangerous
- Ender echo with a rider is the most likely desync. A ridden horse's movement belongs to the controlling client. I move it server-side and hope the client accepts the position. If you rubber-band back, or the horse and your camera disagree about where you are, that is this.
- Food preference depends on handler ordering, not on anything the type system protects. It registers at HIGH priority so it sees the interaction before the diet handler and cancels. If another mod also wants that event at HIGH, the gene silently does nothing - which is the exact failure this project already tracks by name.
- Hydrophobic is CONFIRMED, and this entry was wrong about it (owner, 2026-09-13: "hydrophobic works AND it seems like the horse moves for an edge after too?"). It used to say the "and then heads for the nearest shore" half was not implemented and that the horse was "simply dumped where it stood" - written from reading the translator, which only ejects. The heading-out is vanilla's own behaviour for a horse in deep water, and the gene inherits it for nothing. A good reminder that reading the code tells you what your code does, not what the player sees.
- Leader of the pack is the performance one. Six followers pathfinding continuously, and pathfinding is the most expensive thing a mob does. One horse is certainly fine. A stable with several pack leaders in it is the case I have no feel for at all.
Two performance bugs found while reviewing, and what they suggest
Both were fixed before shipping, and both are worth recording because they are the same mistake in two places and it will happen again.
- The world-reading condition flags were computed all together. A caveborn eyesight horse asks for one block-light read and was paying for a two-thousand-block jukebox search and a sixteen-block entity scan, every twenty ticks, for ever. Eyesight is one of the more common genes here, so this would have been a real and entirely invisible tax. Now only the flag actually named is computed.
- The guardian's "cheap early-out" did not exist. Its javadoc claimed it established ownership before touching the world; in fact it scanned a sixteen-block box for horses on every hit any player took anywhere, and then checked ownership. The horse tick now keeps an owner index and the event does one hash lookup. The lesson is that a comment asserting something is cheap is not evidence that it is, and I wrote that comment myself in the same session.
If the game stutters in a way that correlates with horses rather than with anything obvious, the shape of both of these bugs - a per-entity cost paid by everybody, hidden behind a claim of cheapness - is the first thing to go looking for.
Start here — what is left that can damage a world
- Spontaneous breeding is the one to watch first, and the hardest to see. It runs while you are asleep. Put four expressing horses in a paddock, leave the world running, and come back: the local cap should hold the population at six and then stop for ever, not creep. If it creeps, nothing else in this list matters.
- Holy ward must not break a mob farm.
Build or borrow a spawner-based farm, stand a warding horse next to it, and check
the farm still produces. The ward is meant to cancel natural spawns only;
if a spawner or a spawn egg stops working, the allow-list in
GeneWardHandler.isNaturalis wrong. Also worth watching: does the ward actually follow the horse, and does it stop within a couple of seconds of the horse dying? Entries expire after 40 ticks rather than being removed on death. Spawn eggs are owner-confirmed to still work; how to see the ward refuse something is on §0-BX. - Egg layer must stop when the ground is full. Leave one overnight in a closed pen. The nearby-cap should stop it at eight of the item, not carpet the floor.
The ones most likely to be quietly wrong
- Food preference beating the diet.
The whole point of the locus. Find a horse whose favourite its diet forbids and
feed it. It must accept. If it refuses, the handler ordering has lost to
HorseDietHandlerand the gene does nothing at all — which is the failure mode this project already tracks by name. - Ender echo with a rider aboard. Get shot while mounted. You should arrive somewhere legal, still seated, without rubber-banding. A ridden horse's movement is owned by the controlling client, so this is the most likely place in the batch for a desync.
- Leader of the pack at scale. One is fine. Six followers pathfinding continuously is the cost, and the interval and target cap are guesses. Watch the tick time with a full retinue.
- Echolocate in a busy cave. Its cost is packets, not ticks, and that does not show up with one horse in a field. Ride one into a large cave system and watch for network stutter.
- Hot blooded in a snowy biome. The melt/refreeze loop is the thing to catch. Stable one in a snow biome and leave it. Ice melts to a water source rather than to air, deliberately — check that a horse on a frozen lake ends up swimming rather than falling through into a hole.
Feel, which no test can reach
- Do the fighters feel like guards or like liabilities? Gladiator and guardian both hold a radius and never chase, which was a settled decision precisely so they do not die forty blocks away. If they still die a lot, the radius is wrong rather than the rule.
- Is intimidating's cost too high? It empties a farm, on purpose. Whether that is a memorable trade-off or just annoying is a judgement only play can make.
- Are the sound genes bearable in a herd? Singer, meowing, base alarm and echolocate all have cooldowns chosen by guesswork. Base alarm is dominant, so several in one paddock noticing the same skeleton is the normal case.
- Does eyesight's torch trade-off land? A caveborn horse gets slower the more you light the tunnel. That is deliberate and may simply read as a bug.
- Are the weather loci noticeable at all? They only express when the sky agrees, and the magnitudes are a first guess. It is the one locus family you cannot check on demand.
Frequencies, which want a few hundred wild horses
Every carriers-only locus — fireproof, holy ward, ocean-born, bird boned, gladiator, guardian, ender echo, spontaneous breeding, and all four matched-pair loci — is invisible in the wild by design, so the only way to judge the rates is to test a lot of horses through the gene database. The matched-pair loci are the ones to doubt: with dozens of alleles, finding two carriers of the same one may prove so rare that nobody ever does it. Spawner has the largest roster and is the worst case.
§0-BS — Molten hooves: prints on the ground (2026-09-10, rendering owner-confirmed)
Molten hooves lays the mod’s own flat print particle, one per half-block travelled, and the owner has seen it work ("looks pretty good to start with"; the sprite is theirs to redraw). The allele redesign is on §0-BY. What is left here:
- Spacing and fade. A walk should leave an even track; a gallop,
prints further apart; standing still, nothing. Size, spacing and life are three
constants (
HALF_SIZE,STRIDE,LIFETIME). - Uneven ground. Stairs, slabs, snow layers, the edge of a drop. A print should sit on the surface under its hoof and none should appear over air or water.
- A colour horse may burn blue, deliberately: the hue rolls over the whole circle. Decide whether that is charming or wrong.
- Wild frequency - white 2% one copy and 0.2% two; black 0.3%, colour 0.5%, multicolour 0.2%, homozygotes only. Whether that feels right needs a few hundred wild horses.
§0-BR — Eleven more genes, and dorsal wing's underline (2026-09-10, NOT looked at in game)
Agatebound, bargello, bracketed, coronal, geode, maelstrom, nacre saddle, starburst, sunspiral, wing margin and witchfire. All eleven rendered and looked at as a contact sheet; none has been in the game.
- Three were rebuilt on the way in and are the ones to look at — geode was scaled up by about a third, starburst's three nested stars were made disjoint, and wing margin's heavy veins were re-spaced from an angle that put none of them on the horse. All three now pass the dead-layer check, which is a statement about presence and not about whether they look right.
- Geode is still one-sided. It renders as shards up the hind leg and rump rather than up all four legs, which may be the wave phase or may be the gene doing what it says. It was three hundred texels before and is several times that now, so it is at least visible; whether it reads as crystal is a question for a real horse.
- Nacre Saddle is a rename, not a new gene name the author chose. If it turns up in a file or a note as plain “Nacre”, that is the reason, and the other Nacre is the cracked-plate one.
- Three of the eleven carry nested same-field thresholds with no subtraction — agatebound, bracketed and nacre saddle — which is the shape that made contour paint a white horse. All three render acceptably, so they were left alone, but they are the first place to look if any of them reads as washed out in game.
- Dorsal wing stops about two and a half units above the underline now. Confirmed in a render on a palomino. What is unchecked is how it sits on a horse with a low-slung barrel — the cut is a fixed height in whole-horse space, not a fraction of the barrel.
§0-BQ — Four of yesterday's intake genes retuned (2026-09-10, NOT looked at in game)
All four were rendered and looked at, on their own preview base and on a second coat, before and after. None has been in the game.
- Contour is a different-looking gene now, not a tweaked one. It was near-white with a brown patch and it is a saturated green-to-red-brown elevation map. If it reads as too much, the thing to change is the palette rather than the layer structure — the bands being disjoint is what makes any palette work at all.
- Contour's coloured form can come out nearly monochrome and that
is not a bug:
inkHueandhighHueare independent draws, so some horses will roll two hues that sit next to each other. Worth seeing how often it actually happens before deciding it is a problem. - Dorsal wing's flank is an extrusion, not a drawing. It renders as wings folding over the barrel. Whether it still reads as a butterfly from a player's eye height, rather than as a dark saddle with teal edges, is exactly the question a 150-pixel render cannot answer.
- Rising sun now paints over nearly everything — priority 620. A horse carrying it and any other marking will show the ribbons and very little else, which is intended and will look like a bug the first time it happens.
- Dripwork's runs are
STROKESweighted low. They read on a palomino and on a chestnut. Nobody has checked them on a horse with white legs, where black runs over a sock is the interesting case.
§0-BP — Fourteen genes out of intake (2026-09-10, NOT looked at in game)
Blackwork, coastline, contour, crazework, dorsal wing, dripwork, dustfall, overcast, ringwork, rising sun, serpentine, shallows, squiggle and teardrop. Every one of them was rendered and looked at — a contact sheet of all fourteen icons, which is how dorsal wing was caught painting a plain black horse — and none has been in the game.
- Dorsal wing is the one to look at first. It was rebuilt this session, from stacked layers to disjoint ones, and it is the only gene here whose paint changed rather than just arrived. It renders correctly on a black horse (its declared preview base) and on a palomino. What no render settles is whether a butterfly along the spine reads as a butterfly from the angle a player actually sits at — the gene's own notes admit it is “modest from dead level”, and nobody has been at dead level.
- Blackwork and dorsal wing carry simplified drawings. Their paths were flattened and reduced to 700 points from 4368 and 1637. The silhouettes are identical to well under a texel by construction, but that is an argument rather than an observation. If either outline looks wrong in game, that is where to look.
- Overcast has a third allele nobody asked the author for.
Ck, a black sky, added by the three-form rule. It is the first gene the rule was applied to as a rule rather than in a sweep. - Every founder table here was re-derived, so these genes are three to six times rarer in the wild than their files originally said. If they seem not to turn up, that is why, and it is deliberate.
§0-BO — Forty-two black alleles and a split Cleave (2026-09-10, NOT looked at)
This is the largest single change to what the coat engine can draw since the import, and almost none of it has been looked at. What is established is narrow and worth separating from what is not.
Nothing that existed changed, except three white forms on purpose. The bake golden gained 42 rows, lost none, and moved exactly three — pavonem, concentric eyespots and scarab dapple, the three whose white form was regraded. The pipeline golden moved six rows, all of them the one genuinely new Cleave horse.
Looked at, on a bay, in a render: moonwing black (a graphite
wing with the dust and the gold intact — the best of them), snow cloud
black, pavonem black and its regraded white, concentric eyespots both ways, and
all four Cleave combinations including the heterozygous Wve/n.
That is six genes out of forty-two.
Not looked at at all: the other thirty-six black forms. They were produced by one transformation rather than one at a time, so they are likely to be right or wrong together rather than individually — but the failure mode that matters is per-gene and cannot be measured: a near-black marking on a dark coat is a marking nobody can see. Every black form was rendered against a bay by the icon baker and none is blank, which is the floor, not the bar. The horses to look at are the black and seal brown ones, and nobody has.
- The regraded white forms are a visible change to genes that already
shipped. Pavonem's outer leaf went from warm ivory to a light grey
and its pupil from white to mid-grey; concentric eyespots' outer band went
from off-white to a dark grey. Both are more legible in a render than what
they replaced and both are different. If either reads worse in
game, the band to move is
LIGHT_LOin the transformer's docstring, and the fix is a hand edit — the transformer is not meant to be run twice. - Cleave's founders are thin. The colour locus shares one
RARE budget across nine expressing pairs, so every one except
Clvw/nis under 0.002%. Wild-caught Cleaves will nearly all be white front halves; the black and back-half ones are breeding projects. That is the founder budget working as designed, and it is worth knowing before somebody reports the back half as missing. - A breed cannot make a back-half Cleave.
BreedFounderforces a named modifier wild unless the breed lists it, so every breed horse'scleave_sideisn/n. Same as accretion field, and untested there too.
§0-BN — Four genes retuned and one new one (2026-09-10, NOT looked at)
All five were checked the way this project keeps having to learn to check a coat — rendered through the icon tool’s own camera and looked at, not reasoned about from the numbers. That is enough to say a gene paints where it was meant to. It is not enough to say it looks right on a moving horse in daylight, which is what these want.
- Coral bloom lost its orange. The seams are bare now, so the ground is whatever the horse’s own coat is. On the bay the icon uses that reads as blue lobes on brown, which is the intent — but the gene has only ever been looked at on a bay, and the one to check is a chestnut, where the seam colour and the pale crown are much closer together.
- Moonwing is about four times the marking it was and now wraps the topline. Confirmed in a render on both alleles. What no render can answer is whether a wing that large still reads as a wing rather than as a blanket at the distance a horse is usually seen from, and whether the shape survives the neck, which the enlarged viewport now reaches into.
- Moonwing pearl also gilds and dusts every other white marking. Rendered on a splash-plus-sabino horse, where the gold rim round the white is unmistakable. Two cases are only measured, not seen in game: a horse with no white but the wing (the rim layer selects nothing, as intended), and a horse that is white all over — see gap 166, where the pearl form’s gold comes out grey for reasons that predate this change.
- Iridescent rosette’s pale allele is three greys. Rendered and clearly banded. Its wiki icon now shows the coloured form instead of the pale one, which is not a bug and is worth knowing before someone reports it: the icon tool photographs whichever allele moves the most texels, and the darkest of the three greys sits close enough to a bay to cost the pale form the count it used to win on.
- Nymphaline is new and has never been in
game. Both forms render. The dominant form reads as intended. The frosted
recessive is the one to look at:
Wf/Wfcomes out very close to a plain white horse in a 150 px render, and whether its grey-green venation is legible at all is exactly the kind of question a thumbnail cannot answer.
The gene files’ own notes moved from the gameplay tab to the coding tab on all 56 generated gene pages that carry them. Nothing to look at in game; it is listed here because a reader who knew where that prose was will not find it where they left it.
§0-BM — What the drawing-engine change did to the genes that were already here (0.4.1, 2026-09-09, NOT looked at)
Twenty-two genes and three masks landed at once, and the honest question after a change that size is not “do the new ones work” — that is §0-BL — but what did it do to the hundred and twenty that were already here. The answer splits cleanly in two, and the two halves want completely different amounts of attention.
No existing horse changed colour. Forty-three existing genes got rarer in the wild, some of them by a factor of seven. Nothing else moved.
Confirmed, by measurement: not one existing coat moved
This is not a judgement, it is a hash comparison, and it is the one thing on this page that does not need a play session.
- All 1056 composed coats in the pipeline golden are byte-identical before and after. The file’s every line changed, which looks alarming until you read which half: the key is a genotype code and it got twenty-two segments longer. The hash on the end of each line is the same on all 1056.
- All 620 rows of the bake golden are unchanged, and 57 new rows joined them. Not one pre-existing gene×allele hash moved.
- That covers the four masks whose code was edited —
SPOTS,RINGS,CRACKLEand theRAMPop. Every new parameter defaults to the behaviour that was there before, and the goldens are what say so rather than the intention.
So no gene needs re-verifying for appearance. If a marking you knew looks different in 0.4.1, that is a bug and a serious one, because two golden files say it cannot be.
Not confirmed, and the reason this section exists: forty-three genes got rarer
intake/tools/founders.py was re-run over the whole set, which is what it is
for — it budgets the tiers together, so adding genes necessarily moves
everybody’s numbers. What it also did was flatten forty-three tables that had
been sitting above their declared tier, some of them well above.
Across the whole mod the share of founder horses expressing some magical gene
went from 16.32% to 13.35% — and that is with twenty-two new
genes added, so the existing ones absorbed rather more than that figure suggests.
The ones that moved by more than a factor of two, worst first. None of these is a coat change; it is purely how often a wild horse turns up carrying one.
| Gene | Tier | Founders expressing, before | after | factor |
|---|---|---|---|---|
| Banded Socks | COMMON | 0.800% | 0.120% | ÷6.7 |
| Ocular | EPIC | 0.150% | 0.020% | ÷7.5 |
| Tron | EPIC | 0.200% | 0.028% | ÷7.1 |
| Picasso Marking | RARE | 0.300% | 0.040% | ÷7.5 |
| Dorsal Shield | UNCOMMON | 0.440% | 0.112% | ÷3.9 |
| Duskfall Speckle | UNCOMMON | 0.440% | 0.112% | ÷3.9 |
| Tidemark | UNCOMMON | 0.440% | 0.112% | ÷3.9 |
| Webbed | UNCOMMON | 0.440% | 0.112% | ÷3.9 |
| Wing Cloak | UNCOMMON | 0.440% | 0.112% | ÷3.9 (and still killswitched) |
| Lace | RARE | 0.230% | 0.056% | ÷4.1 |
| Stained Glass | RARE | 0.180% | 0.056% | ÷3.2 |
| Cleave | RARE | 0.154% | 0.056% | ÷2.8 |
| Yalia | UNCOMMON | 0.236% | 0.112% | ÷2.1 |
| Bloodstained | RARE | 0.090% | 0.040% | ÷2.3 |
| Nyxborn | EPIC | 0.050% | 0.020% | ÷2.5 |
| Koi | EPIC | 0.060% | 0.028% | ÷2.1 |
Another twenty-seven moved by less than a factor of two — mostly RARE and EPIC markings settling from 0.088% to 0.056% and from 0.058% to 0.028%, which is the tier budget doing exactly what it says. One went up: Striped Mane and Tail, 0.140% to 0.168%.
This is the decision to look at, and it is not a bug report.
Every one of those numbers is what the gene’s own declared rarity tier says it
should be; what changed is that the tier is now being enforced where before some tables
had drifted above it. Whether Banded Socks at
0.12% is right is a taste question about how often a player should meet one,
and the answer might well be that it was tiered wrongly rather than budgeted wrongly.
The fix, if the rates are wrong, is to change the gene’s
rarity and re-run founders.py — not to
hand-edit a founders table, which is exactly the drift that produced this.
Existing worlds: they load, and they load a little wrong
- A horse saved before 0.4.1 loads.
Genotype.parsedrops a segment for a gene it does not know andGenotype.offills every missing gene with its default allele, so an old horse comes back with all twenty-two new loci at wild type. It keeps its coat, because the pipeline golden says its coat did not depend on them. - But it can never have carried one, which is the part worth
checking. Every horse in an existing world is
n/nat all twenty-two loci for ever, and so is everything bred from two of them. The new markings can only enter an old world through a newly spawned wild horse — a new chunk, a new herd, a stable, a spawn egg. On a world where the areas you play in are already generated, that is close to never. - The thing to actually try: load an existing save, check a horse you know looks the same, then go find unexplored ground and look at a wild herd. If the new markings never appear anywhere, that is the expected behaviour above rather than a defect — but it is worth confirming they appear somewhere, because “the founder table is right and nothing ever rolls it” is a failure this page has seen before.
- The genotype code is 22 segments longer. It is sent on the coat
packet, stored on the spawn egg and on a genome jar, and
gap 135 is the release that disconnected
everybody by crossing a string cap nobody had written down. The caps all come from
GenomeCodeCodecsnow andEpigenomeSizeTestguards each at half budget, so this should be fine — but 0.3.0 and 0.3.1 also “should have been fine”, and the symptom is that entering a world with a horse in view disconnects you. First horse you see is the test.
The two editors, which are the same screen twice
- The gene creator (
wiki/gene-creator/) offers three new masks with parameter kinds it has never had — a textarea for path data that reports what it parsed, aviewBoxfield, and two checkboxes that are ticked by default, which no mask flag has ever been. Add anSVGmask to a fresh gene and check: the preview draws the starting teardrop, the note under the path says “points in N subpaths”, and untickingfillexports"fill": falserather than dropping it. Its own boot-time parity self-check has to stay green too. - The horse designer (
wiki/horse-designer/) runs the real engine as WebAssembly and was re-baked, so it should need nothing — but it is the surface where a staleweb.wasmshows yesterday’s mod convincingly. The twenty-two new genes should be in its gene list, grouped by family, and a horse rolled there should match one spawned in game from the same code. - The spawn screen is the designer’s twin and is unchanged by this work, but the gene list it draws from is 22 longer. Check the list scrolls and that nothing overlaps at GUI scale 4, which is the size that has produced two reports already.
Everything downstream of “how many genes are there”
- The gene database and the allele collection both count genes and both hide what you have not met. The denominators moved by 22 loci and 47 alleles; the browser should say so rather than showing a stale total.
- Gene carrots. Every new gene takes the default carrot block, so all
twenty-two are craftable and all twenty-two are on the Unknown Gene Splice table.
check-recipes.mjssays no two recipes claim the same inputs, which is the collision that matters; what it cannot say is whether the splice table is now so wide that the carrot is useless. - The landing page says 225 genes and both numbers on it are computed from the registry rather than typed. Worth one glance that they are not obviously wrong.
§0-BL — An SVG mask, three new masks, and twenty-two genes (2026-09-09, NOT looked at)
The largest single addition to the drawing vocabulary since it existed, and none of it has been seen on a horse in the game. It has been seen on the icon baker’s contact sheet, which is a render of the real engine and is how four defects in it were caught, and that is all.
The engine
- Does an
SVGmask land where it says? Moonwing is the one to look at — a drawn wing on both flanks, filled, with the same path stroked in gold round its edge. The three things that would each look deliberate while being wrong: upside down (the y flip), mirrored the wrong way (the plane), and the gold band not following the fill’s edge (the stroke and the fill disagreeing about the viewport). A unit test asserts all three against body coordinates; none of them has been looked at by a person. - How long does a horse take to make? The point ceiling is 1024 and every mapped texel walks every segment. Moonwing’s wing flattens to a couple of hundred, and there is a per-subpath early-out, so it should be free — but the number to watch is a horse carrying Moonwing and several other magical genes, and the place to see it is the coat-bake time in the log rather than a stopwatch.
FAN: are the bars the right size? Itsspacingis an angle, and the first draft of the schema defaulted it to about three bars per full turn. Morpho Wing and Gill Bloom were both retuned after the contact sheet showed a single bar covering the whole marking. On a horse, check the bars widen as they leave the pivot — that is the whole reason the mask exists, and a parallel-looking fan means the pivot is somewhere the marking is not.NORMAL: is the sheen continuous or faceted? Carapace Sheen runs it atround: 0.85. At 0 a Minecraft horse is boxes and the sheen would read as three hard zones; the blend toward an ellipsoid normal is what makes it a curve. Look at the shoulder and the point of the hip, where the box corners are, and check the transition does not band.CRACKLE measure: "centroid": is the core inside its cell? Iris Bloom Diamonds, Nacre and Tidefoam Sash all depend on it. The failure to look for is a core or a highlight sitting across a wall rather than in the middle of a polygon — which is exactly what the import was worried about and the parameter was added to prevent, so if it is happening the parameter does not work.
The twenty-two genes
All present in the world at their tiered founder rates, all reachable in the designer and the spawn screen. Spawn each one rather than breeding for it. The four that were retuned after a render, and so are the least settled: Morpho Wing, Gill Bloom, Concentric Eyespots and Fish Scales.
- Is anything invisible? The rule is half a body unit — a texel — and Concentric Eyespots shipped from the import with bands half that wide, which drew nothing at all. Its bands are roughly doubled now. Any gene whose marking you cannot find is that failure until proved otherwise; check it against the scale rule before assuming anything else.
- Do the recessive/coloured pairs actually differ? Fifteen of the twenty-two ship as a pale dominant and a coloured recessive drawing the same shape. Breed the recessive out on one line and look at the two side by side; if they are indistinguishable, the hue knob is not reaching the layer that was supposed to carry it.
- Moth Eyes only shows on black or grey. That is two LUMA readings — darkness and how far the colour sits from grey. Try it on a liver chestnut (should stay clear) and a pale dapple grey (should take it). Those are the two the brightness reading alone gets wrong, and they are the reason the second reading is there.
- Orchid Frost is supposed to do nothing on a pale coat. Not a region exclusion — the blotches are drawn, and there is nothing left for them to take. On a cremello or a grey it should be invisible; on a black or a liver chestnut it should be obvious.
- Emissive: five of them glow. Emberveins, Morpho Wing, Moonwing, Nightbloom Shroud and Opal Crackle. Look at one at night and one in a lit stable.
The one thing that is confirmed is that all 22 register, parse, take a genotype slot, appear on the landing page and bake an icon — and that no existing gene’s coat moved: 57 rows joined the bake golden and not one existing hash changed. Everything above is about whether the markings are any good, which no test can answer.
§0-BK — One page for making a gene, in eight tabs (2026-09-09, NOT looked at)
Documentation only — no behaviour changed, and the eight Java edits in it are comments and test messages. What wants looking at is the page itself, because it is the first one on the wiki to use a mechanism at this scale.
- Does the tab bar render with eight buttons?
Making a gene is the only page with more than
three.
.tab-bargainedflex-wrapfor it; check it wraps rather than overflowing at a narrow window, and that the three-tab pages (anygene-*.html) are unchanged at every width. - Does it open on Start here? Every panel is page-local, so
tabs.jsfalls through its stored-view logic to the first panel. Arrive from the sidebar (which appends?view=coding) and from a bare URL. - Is it purple? The page sets
data-view="coding"on<html>by hand, becausetabs.jsonly sets that for a real view tab. If the accent is grey rather than the coding purple, that attribute is not surviving. - Do cross-tab links switch tabs?
tabs.jsresolves an in-page link byquerySelector, so a link to a panel rather than to a realidsilently does nothing. Try Start here → The file, Start here → In Java, and the Effects tab’s links out to horse-traits. - Is it in the sidebar under Coding only? It should be absent from the gameplay and science views entirely.
The three deleted pages — creating-a-gene,
gene-format, modding — and gene-effects
had roughly 190 inbound links between them, all rewritten to the tab their material
moved to. check-links.mjs passes and reports no orphans, which proves every
href resolves; it cannot prove any of them lands somewhere sensible. A spot
check from a gene page and from the roadmap is worth a minute.
§0-BJ — A stall that stopped killing horses, and eight things nobody has touched (2026-09-09, NOT looked at)
Confirmed in play tonight, so deleted from the list above: binding a stall sign; spending a ticket to bring a horse home; shearing; milking a waterborn mare; research papers off a book; the Getting Started tab; the Alleles tab collecting; the cowboy and horseman reading as they/them; and the gene-preview horses turning in 3D.
- The rewritten stall detector, in a stall with a fence and a gate. Owner-confirmed 2026-09-10: the sign binds and finds the inside of an ordinary stall. (Where the horse lands is on §0-BX.) Then the cases the new rules are guesses about: a stall floored with slabs or carpet (should be one room), a floor with a one-block step in it (should still be one room), a two-block drop (should not), and a stall whose gate is standing open (should still stop at the gate - that is deliberate and is the rule most likely to be argued with). See gap 153.
- A ticket into a stall with nowhere to stand. Fill a bound stall with hay bales and spend a ticket on its horse. It must refuse, say why, and not consume the ticket - the old code invented a spot and suffocated the animal. Then the awkward ones that are still unproven: a stall in an unloaded chunk, and an interdimensional ticket used from the horse dimension.
- Taming by hand is owner-confirmed. Still unwatched: whether horses peel off a wild herd when you only walk past crouched with food, that a carnivorous horse ignores a carrot, and that a dhampir does not come at all. Gap 155.
- Bareback steering, and the saddle you should never see. Get a horse to attentive/follows - bond 81 - then ride it with no saddle. It should steer and jump like a saddled horse and show no saddle on its back. Then the part that matters: open its inventory while riding and try to take the saddle out. You should end up with nothing. Dismount and check the horse is bare again, and that a horse you saddled yourself is never touched. Gap 156.
- The Breeds tab. Both known faults are fixed and waiting on §0-BX. Then look at the entry itself - the plate horse, the biome list, the body scores, and whether “known to carry” naming only discovered genes reads as informative or as broken.
- Hearts when the bond moves, and where they stop. Hand-feed a tamed horse and watch for hearts. Then keep feeding past the daily cap of 15 and check the hearts stop - that is the only signal the cap exists.
- A foal that already likes you. Breed a well-bonded mare and check the foal's information screen opens at roughly a quarter of hers rather than at zero.
- The research shelf was rebuilt as a chest after it still "did nothing" in play - see §0-BX.
- The tab strip's new order - Getting started, Recipes, My horses, Breeding, Gene database, Alleles, Breeds - and that the gene previews no longer show a wild-type square except on extension, agouti and shade, where they should. The Alleles tab should likewise count every allele at those three and drop the baseline everywhere else.
- Shearing is worth 2 bond now, not 5, which puts it level with a hand-feed and below a treat. Nothing to look at so much as to feel: check that keeping a horse sheared no longer out-bonds actually being kind to it.
§0-BI — A checklist, an allele collection, and a shelf that looks like Minecraft (2026-09-09, NOT looked at)
- Open Getting started and click through the contents list. The
checklist is seven entries at the bottom of it, one per group, each under the
running total. Then go and do one - taming a mare is the easiest - and check it
says so in chat once and the box fills in. (The task count is
ProgressTask.values().length; the sweep that proves each is wired istools/check-progress-tasks.mjs.) - Relog and check the ticks survive. Progress is a {@code SavedData} keyed by player and pushed on login; if it comes back empty, the login sync is not firing.
- Watch which tasks tick when you breed one foal. All three zygosity boxes will very likely tick at once, because the check walks every locus (gap 148). Whether that is the right amount of teaching is a judgement only playing it can make.
- The three bond tiers tick. Ride and feed one
horse until its information screen says attentive, and check the checklist
says so at 31 rather than at some other number. The tiers are credited from
syncCare, so a tier reached while the horse is out of your sight is the case to watch. - The browser's scroll bars drag. Confirmed by the owner on the gene list. The other eight have not been: the tab strip's horizontal bar, both breeding-preview pickers, My horses, Recipes, the Alleles page and the two detail panes. Clicking the bare track should jump the thumb under the pointer.
- The shelf's item icon. It was the missing-texture check pattern:
the model was in
models/item/, and 26.1.2 readsitems/. It should be a bookshelf now, in hand and in the inventory. - Spawn an unattached signed transfer paper in creative. It should
look like a blank transfer paper rather than nothing at all - the item model is a
minecraft:conditionon whether the deed component is there.
§0-BH — Spawn moved under the horse (2026-09-09, NOT looked at)
Reported: “Clear genes” and “Make egg” overlapping on the custom spawn egg’s screen — gap 139 arriving exactly as predicted. Spawn is now centred in the empty strip under the preview panel rather than being the third button in the right-hand column, which gives that column back a whole row.
- The overlap should be gone at any ordinary window size. The arithmetic says the two groups clear down to about 258 pixels of window, where they used to collide below 314 — and a 1080p screen at GUI scale 4 is 270, which is where the report came from. Worth checking at GUI scale 4 specifically.
- Is Spawn findable there? It is the one button that does the thing, and it has moved out of the column where every other button lives. If it reads as decoration under the horse rather than as the action, say so.
- Check it in non-creative too: it reads “Spawn (creative only)” and is greyed out, which is a longer label than the space used to allow.
- The designer took the same shape — the horse designer put Reroll name in the slot the screen gives Spawn, so its column is three rows too and the two stay the same screen in two places.
§0-BG — A Getting Started tab, a copy that takes time, and stables out of the mountains (2026-09-09, NOT looked at)
- Open the browser on a fresh install. It should land on
Getting started, once. Switch away and it should never open there
again — that is a client config (
tutorial.seen), so set it back to false to test the first-run path twice. - Read the whole page. Thirteen sections, and the two things to look at are the pictures: a horseman villager and a cowboy, drawn as live entities. The horseman is the risky one — if he renders in plain villager clothes with no profession, the picture is worthless and should become the Horseman's Table block instead (gap 146). Check the scroll bar matches the content, too; its length is computed from the page's own height.
- Close the browser mid-page and reopen it. It should come back to the same tab, the same scroll position, the same selected gene, the same search text and the same sort. That is now session-wide state; only the horse-specific selections are dropped, and only on disconnect.
- Copy a gene on the shelf and watch the bar. The arrow between the book and the result fills up, and the line underneath counts down in seconds. A common gene is about ten seconds and a mythic one about a minute — one iron ingot's smelt per rarity tier. Pull the book out mid-copy and progress should reset to zero rather than pause.
- Two players at one shelf should each be able to copy their own gene onto their own book: the work is ticked per open menu, not per block. Untested and worth one look if anybody has a second client.
- Find a generated stable. They were turning up buried in
hillsides; the three structures now carve their whole bounding box clear
instead of laying a thin skirt underneath
(gap 147). This needs a new world -
an already-generated stable will not move. If they still sit badly, the next
thing to try is dropping
meadowandsavanna_plateaufrom the biome tag, since those are mountains in all but name.
§0-BF — The Equine Research Shelf, and three smaller things (2026-09-09, NOT looked at)
A block, a block entity, a container menu, a screen and two payloads, written in one pass (gap 143). Start by placing one; if the model or the screen is wrong, everything below is moot.
- Craft one (1 bookshelf + 2 horse hair) and place it. It should look like a bookshelf. Right-click opens a two-tab window.
- Store tab: file a paper. Put a research paper in the slot; it should vanish and the gene should appear in the list. Filing a second paper for the same gene should do nothing and leave the paper in the slot rather than eating it.
- Craft tab: copy it. Pick the gene, add a blank book, take the paper out. The book is spent and the shelf keeps its original, so a stack of books should give a stack of papers.
- Take the original back from the Store tab and the gene should leave the list and stop being copyable.
- Save, quit, come back. The single most valuable check: the contents are a gene-key set on the block entity and nothing has round-tripped it.
- Break it. Every filed paper should drop along with the block.
- The tabs must gate the slots. On Store, the book and result
slots should be gone - not merely invisible. Try clicking where they
were: if an item goes in,
Slot.isActive()is not gating hit-testing the way this screen assumes and the whole tab mechanism needs rethinking.
Also in this build, and unrelated:
- Break one hay bale out of a lit horse portal. The whole interior should vanish, not just the bale. Then light a fresh portal - that is the half that could have broken, since the fix makes a portal block delete itself when it is not enclosed and a portal is briefly not enclosed while it is being filled in. Both the overworld portals and the horse dimension's return portal are worth lighting.
- The Recipes tab's category dropdown. Two entries, "Everything else" (the default) and "Gene carrots". The gene carrots were burying the 27 recipes that are not gene carrots. Searching inside a category should stay inside it.
- Every recipe now has a line saying what the thing is for, under the grid. The gene carrots' line is formulaic and names the gene. Worth reading a few for length - the panel is a fixed 210 pixels tall and the longest blurb (the unknown epigenetic splice) is the one that would overflow first.
§0-BE — What is left of the H menu's conversion (2026-09-09, part confirmed)
The browser opens, draws and reads correctly after losing its container — "the H menu looks great". That was the load-bearing question on this section and gap 141 closes with it. The tab strip has since gained scrolling, because six tabs ran off the edge.
- The Recipes tab. Every recipe the mod adds, drawn as its grid
and result, plus one row per discovered gene for the splice carrot. Worth
checking: that the shapeless ones read sensibly laid out left-to-right, that
the two
#minecraft:fencesingredients resolve to a real fence rather than a blank, and that hovering a cell gives the item's tooltip. It makes nothing — that is the point. - Type “speed” into the gene search. The reported bug: the e closed the window and opened your inventory. A focused text box now swallows every key but Escape. Check that backspace, the arrows and ctrl+A/C/V still work in the box, since those go through the same path.
- Right-click a horse with a book. You should get a research paper for one gene that horse carries, at random, and a chat line naming it. On a completely ordinary horse: a different line, and no book spent. This is the replacement for the browser's old Craft research paper button, which is gone.
- Feed breeding carrots to two mares (or two stallions). They should court, spend the carrots, produce no foal, and now say so — one of three lines per sex, only to the player who fed them.
- Sex symbols on nameplates. ♀ in pink, ♂ in blue,
after the name. The one real unknown: whether they render as glyphs or as
boxes — both are outside ASCII and come from the unicode fallback
font, which nobody here has tested. If they are boxes, say so and they can
become drawn shapes like the browser's padlock.
nameplate.sexSymbolin the client config turns them off.
§0-BD — A gene says what it does when you point at it (2026-09-09, NOT looked at)
Hovering a gene in the custom spawn egg's list now pops a panel with the gene's name and its one-to-three-sentence summary. It sits to the right of the list, which is empty space on that screen, and it is drawn the same way the dropdowns are rather than as a vanilla tooltip — a list row is not a widget there, and the browser twin has no vanilla tooltip to mirror.
- Hover a gene that is on the horse, and one that is not. Both should give the same panel. The one case worth pushing on is a long blurb near the bottom of the list: the panel is pushed back inside the window rather than allowed to run off, so it should ride up rather than get cut.
- Is it in the way? It covers part of the 3D preview while you are pointing at a gene. That was the deliberate choice — the preview is not what you are reading at that moment — but it has never been looked at with a horse actually standing there.
- Does it flicker or lag the list? It is rebuilt every frame, including the word wrap. Nothing measures that.
- Seventeen of the blurbs are new and unread in context. Every
registered gene now has one (it was 185 of 202), and
GeneDescriptionCoverageTestkeeps it that way. The fifteen written this session were compressed from each gene's own wiki page: tiger eye, leopard, PATN1, PATN2, shadowcreature, and the ten magic utility loci. Worth reading a few in game for tone and length — they were written to the existing entries' style, not measured against the panel. - The browser twin took the same panel. The horse designer draws it fill for fill, so a look there is a second look at the same change — and its gene list is the easier place to scan a lot of blurbs quickly.
§0-BC — Four things off a real play session, and the one that needs a fresh world (2026-09-09, NOT looked at)
0.3.2 launches and makes a world. The owner confirmed it, which closes §0-BB's first and largest question. What follows are the four things that session then found, three of them fixed by reasoning rather than by being watched working.
- A stable with horses in it — and the empty ones you already have
should fill themselves. Three stables in four generated empty
(gap 136), and the fix is reasoned from
how jigsaw rotation moves a bounding box, not observed. An existing world is
the better test, not a worse one: a stable is only recorded as claimed at
the moment it is populated, so the three quarters that were never
queued were never claimed either. Load a save with a known-empty stable, get its
chunk to reload (quitting to the title and going back in is enough), and walk
back to it — the horses should now be there. A new world should work too;
this is just the quicker check. If it still looks empty, the log says which half
broke:
[Stables] queuedand[Stables] filled … with N horse(s) (X stall, Y field found)are two separate lines, and neither is gated by the debug switch below. - Where the horses stand, once there are any. Gap 82 — the stall scan is a heuristic and has now been shown to be even less observed than it claimed, since three quarters of the cases never got as far as scanning. Horses in a corridor, in a tack room, or clipped into a wall are all live possibilities and none of them has been ruled out.
- No
[Cowboy]or[Horseman]lines in chat. They are now off in a normal install and on in a dev run (gap 137). Two things to confirm, and they are opposite: that a normal install is quiet, and that a dev run still talks — a gate that silences everything everywhere is the failure this switch was built to avoid. The log line[Debug] chat+log diagnostics enabled=…says which way it went. Settingdebug.announce = truein the server config should bring the lines back in a normal install. - The launch log should be quiet now. It printed 121
[genes] could not registerERROR lines before the title screen (gap 138). There should now be none, and two INFO lines instead saying how many genes shipped and how many segments the genotype code has. A collision reported after this change is a real one. - The custom spawn screen's right-hand column. Widened from 96 to 128 with a 4px gutter, and the breed label now fits itself to the button instead of being cut at twelve characters. Worth an eye on whether 128 is actually enough or merely more, and on gap 139: at GUI scale 4 the top and bottom halves of that column still overlap, which nobody has looked at. The browser twin moved with it — the horse designer carries the same numbers, so a glance there is a second look at the same change.
§0-BB — 0.3.0 and 0.3.1 disconnected on world entry; 0.3.2 should not (2026-09-09, NOT looked at)
Reported by the owner’s friends against a handed-off jar, not by anyone here
and not by the suite: 0.2.0 played, and both 0.3.0 and 0.3.1 kick the
client on entering a world with
Failed to encode packet 'clientbound/minecraft:custom_payload'.
See gap 135. It has never been reproduced on
this machine, because a dev-run world is entered before any horse is in view often
enough that it was simply never seen — the trigger is a horse coming into
render range, not the world load itself.
So the first thing to confirm is the plain one, and it wants a fresh world rather than the usual test save:
- Make a new world, find a horse, stay connected. That is the whole test. Walk until wild horses are in view and keep playing for a minute. Before the fix this disconnected on the first one.
- An existing 0.3.0/0.3.1 save should be fine. The fault was in what the server sends, never in what it saved, so a world made under a broken jar should open normally under 0.3.2. Worth confirming with one, because the claim is untested.
- Pick up a preset horse spawn egg and a filled genome jar. These
carry a
stored_genomecomponent that had the same latent fault, and it rides every inventory sync — so it would have kicked whoever held one, in creative or otherwise. Nobody has ever seen it fire; put one in a hotbar slot and see nothing happen. - Open the horse browser and let it list a few horses. The roster packet’s genotype cap moved too, and the roster is the one surface that sends a genome code per horse in bulk.
- Not a visual change at all. No coat, gene, breed or stat moved, and neither golden file changed. If any horse looks different under 0.3.2 than under 0.3.1, that is a separate bug and worth saying so.
§0-BA — The PATH mask, and a checkbox that was never one (2026-09-09, NOT looked at)
Like §0-AZ, no registered gene uses PATH,
so no horse in a world changed and neither coat golden moved. The
exception is the flag fix below, which changes how an existing mask is
edited — and SPOTS is used by shipped genes.
Open the gene creator and load
Prismatic from the examples: it now carries a stroked, smoothed
PATH down the shoulder and a filled crescent on the barrel. Worth an eye:
- The points editor is the drawing canvas now — so the question this entry used to ask (is the textarea good enough to wait behind something else?) no longer needs an answer. What wants an eye instead is §0-CL. The textarea is still under the numbers, and a half-typed line there is still left alone rather than wiping the shape, which is the one bit of its behaviour worth poking at.
fillon a concave shape. The crescent should keep its notch. If a single row of texels through a filled shape ever comes out inverted, that is the even-odd crossing test hitting a vertex exactly on its own ray — pinned inPathMaskTest, but the test sweeps a diamond and a chevron, not every shape anyone will draw.- Does the smoothed curve look like the handles? It passes through every control point by construction. What is unlooked-at is whether that reads right at horse scale, or whether spans between distant points bulge more than expected.
The creator's mask form sent PARTS and CHOICE to their own
editors and everything else to the number / knob / per-dose control.
So SPOTS' mirror — a boolean — was offered as a
number that could be driven by a knob, which is not a thing the game can read.
What to check: open any gene using SPOTS, confirm
mirror is a tick box, that ticking it mirrors the spots, and that leaving
it unticked exports no mirror key at all rather than
"mirror": false. No gene file was damaged by this —
every mirror, invert and emissive in every
shipped and example gene was checked and all of them are real booleans, so the old
control was never actually used to write one.
§0-AZ — The FRACTAL mask, in the creator (2026-09-09, NOT looked at)
No registered gene uses FRACTAL. It is a new mask in
the vocabulary, so it changes no horse that currently exists and moved neither
coat golden. Loading a world proves nothing about it. What is unlooked-at is the
tool: open the gene creator from
file://, add a mask, and pick FRACTAL.
The engine half is covered — FractalMaskTest pins the field, and
check-parity.mjs was confirmed to reach the new code by breaking the JS
divisor and watching it go red. The form is what nobody has opened. Worth an eye:
- The
octavesslider. It is the only integer-stepped VALUE param on a mask other thanCHOICE’s (min: 1, max: 6, step: 1). Confirm it does not offer 3.5, and that dragging it changes the amount of detail in the preview without visibly changing how much of the horse the mask covers — that invariance is the whole reason the mask is normalised the way it is, and the preview is the cheapest place to see it hold or fail. shapeas a dropdown. Three words, defaultfbm. Switching toridgedshould keep the shapes and turn their outlines into the marking.- The tidy() round trip. Every fallback in
schema.jsmatches the Java, so a freshly addedFRACTALmask left alone should export as{"type": "FRACTAL"}and nothing else. If any default leaks into the exported JSON, one of the two tables is wrong. - Speed. Six octaves is six lattice samples per texel, plus three
more if
warpis above zero. The preview redraws on every slider drag; if it feels sluggish atoctaves: 6the ceiling is the thing to argue with, not the maths.
Two FRACTAL layers also went into
example-genes/prismatic.json (a ridged one on the barrel and
a warped fbm one on the neck), so loading Prismatic from
the creator’s examples is the fastest way to see both at once.
§0-AY — Twenty-five science tabs, and three owner’s calls inside them (2026-09-09, NOT read)
runClient item
Nothing on this entry changes the game. It is here because it is unreviewed and because it contains three questions only the owner can answer — read it in a browser, not in a world.
Gap 89’s 25 missing science tabs are all written, and the check now runs with an empty exempt list. The 25 are prose against source material the owner supplied, and none of it has been read back by anyone. What most wants an eye is not the citations but the disagreements: each page now states where the mod departs from the literature, and three of those departures are decisions rather than errors (gap 134).
- SCN4A — the mod kills a horse that
lives. A real HYPP
H/Hsurvives and is merely unregisterable with AQHA; the mod makes it lethal at birth. The page argues the cliff is worth the inaccuracy because HYPP is the one locus where the mistake is made with open eyes. If that reasoning is wrong, this is the one to overturn, and the fix is a severity axis rather than a number. - HMGA2 — the pony allele’s
+2.0health runs opposite to the evidence, which gives that allele a higher-insulin and laminitis risk. The page defends the design reason and says plainly that the sign is inverted. Worth confirming that is the intended trade. - CKM — a speed locus whose only equine performance claim failed replication. The page opens with a warning box saying so. If the mod would rather not ship a locus on that footing, dropping it leaves two speed genes and a much shorter breeding programme — that is the call.
- MATP — pearl is commoner than
cream (
1/22against1/30), which is backwards. This one looks like drift rather than a decision and is probably just a number to change.
Tiger eye and
rabicano were written last, from re-supplied source
files, and carry one flag each. Tiger eye asserts a distinct paler iris for
TE2/TE2 where the literature has one such horse and its phenotype
was confounded by cream. Rabicano’s Rb allele symbol is the
mod’s invention — there is no confirmed rabicano gene at all, only a
research lead near KITLG on ECA28.
Separately, the tabs that already existed now read thin beside the new ones — MC1R at 41 words, EDNRB at 62, MITF at 90 against its PAX3 twin’s 2,024 — and 20 of the 48 natural science tabs name no breed at all. Nothing is broken; it is the same gap one level down, and it is now the roadmap section that gap 89 used to be.
§0-AX — Body size is now a server toggle (2026-09-09, NOT looked at)
body.size, a boolean in the server config, true by
default. False makes HorseRecords.applyTraitsToEntity write a
flat 1.0 to Attributes.SCALE rather than what the alleles
resolved to, so a world keeps every size gene and gets vanilla hitboxes. Design:
Speed, health, jump & size §
body.size.
- Default behaviour is unchanged. The first thing to check, and the
one a mistake here would break for everyone: a fresh world should still produce
visibly big and visibly small horses. If every horse is suddenly vanilla-sized,
the default read is coming back false — most likely the
IllegalStateExceptionfallback inServerConfig.bodySizeActive()firing because the config is consulted before it loads. - Set it false and reload. Edit
.minecraft/phc/server.toml(it moved there in 0.5.000; a per-world override is<world>/phc/server.toml) — then quit to title and come back. A Falabella and a Percheron standing side by side should now be the same height. They re-resolve on the entity tick once per level load, so a horse that was already loaded needs the reload — if one stays big after a full restart,HorseFoundingTickHandleris not re-running. - Does the horse still say it is big? The whole promise of
the setting. The info panel reads the live attribute and should say
1.00; the family tree, the browser and the inspect paper read the genotype and should still show the real size. If the genotype-side numbers went to 1.00 too, the gate leaked past the one attribute write it is supposed to be. - Does tack sit right? The reason the setting exists. Saddle a horse that would have been oversized and look at where the saddle and the rider sit, and whether it fits a two-block doorway (gap 55 should stop applying entirely with the setting off).
- Turn it back on. Reload again; the big horses should come back exactly as they were, because nothing about the genotype was ever touched.
- The
scaleeffect verb. No shipped gene uses it, so this one needs a hand-written gene to test: anattributeeffect namingscaleshould be inert with the setting off, and a modifier already standing should come off on the next reconcile rather than staying frozen on the horse.
§0-AW — A band can follow a pitched part, and six dead layers woke up (2026-09-09, NOT looked at)
Gap 103. The neck’s own geometry used to be
written out by hand in eleven gene files as a sawtooth of wavelength 90 at an amplitude
of 77.94; it is now "space": "local", which asks the part what shape it is.
Six of the eleven had that pair in a normalised space where it cannot work, and were
selecting exactly zero texels — so those six genes have a layer
that has never been seen by anyone, on any horse.
The four genes whose bands did land and whose knobs did not move — cosmic, shark, stars and suit — are byte-identical in the coat-bake golden, so the conversion is a refactor for them and there is nothing to look at. The eleven all still parse, the creator agrees with the game (the parity fixtures reach the new space), and the calibration has three tests under it now.
- The six that were inert. Each of these draws something on the neck or the head that has never existed before, so this is new art, not a regression check: beetle pearl (a pale cap over the poll), diamond scutes (a narrow chain up the crest), duskfall speckle (speckling thickest along the crest), ink scroll and wyrmwood sigils (a collar square to the neck), nebula points (a fan up the crest). The question for each is only whether it looks worth having — the icons say yes, a horse in a world is the real test.
- Goth’s hood, which is the one with history. It went on the
underside of the neck once and had to be reported twice. It should sit along
the crest and over the ears, stop well above the throat, and stay off the face. Its
$depthknob changed units (body units → a fraction of the neck’s depth), so the range of hoods is unchanged but an individual horse draws a different depth than it used to — a goth you have seen before will not look the same. - The collars, specifically. Ink scroll and wyrmwood sigils are the
first two genes to use
axis: "Y"in local space, which is a band square across the neck rather than square to the world. Worth confirming it reads as a band that encircles the neck rather than as an ellipse sliding round it. - The foal. Every check above is on the adult mesh. The foal’s neck is pitched differently (0.611 rather than 0.524) and it has no mane box, so a crest band there is the same arithmetic against different numbers and has never been rendered at all.
- The gene creator.
spacenow offers a fourth option in three places (AXIS, WAVES, RAMP). The dropdown has never been opened; the parity check proves the engine agrees, not that the form draws.
§0-AV — The coat texture cache is bounded, and F3+T now means something (2026-09-09, NOT looked at)
Gap 130, both halves. The client used to keep
every coat it had ever baked until you logged out, and no resource reload touched any
of it. Both caches are now texel-budgeted LRUs and there is a client reload listener.
The policy is unit-tested away from the GPU
(TexelBudgetCacheTest); what no test on this side can see is whether
releasing a texture mid-session upsets the renderer, which is the whole of what is
listed here.
- Nothing flickers, greys or goes white in a crowd. The one real risk in the change: an eviction releases a registered texture, and if it ever released one that a draw call already submitted this frame still wanted, that horse renders wrong for a frame. The budget is deliberately far larger than a frame (a floor of 64 coats sits under the texel budget), so this should be unobservable — stand in a paddock of two dozen visibly different horses, or open the family tree on a large pedigree, and watch for a single-frame flash of the bare white template.
- Editing the gradient and pressing F3+T now redraws every horse. This is
the half a person will actually notice, and it is the easiest to check: edit
common/src/main/resources/.../redblackgradient.png(or drop in a resource pack that does), press F3+T, and every horse on screen should recolour. Before this change it did nothing at all. Switching resource packs is the same test by another route. - The reload does not stutter or crash. The listener throws away the templates and the LUT set as well as the coats, so the first horse drawn after a reload re-reads them and recomposes — the same work a fresh login does, but happening while a world is loaded, which is new.
- The log line at world exit. Leaving a world now writes one line saying how many coat textures and glow masks were released and how many were recycled for space during the session. Nonzero recycling in an ordinary session would be a surprise at the current sheet size and is worth knowing about; a nonzero count with no visual complaint is the eviction path proving itself.
- The “nothing glows” marker changed shape. The emissive
cache used to store a fake
coat_glow/noneid for a horse with nothing emissive; it now stores a realnullentry. An ordinary horse must still not recompose its coat every frame (the dev build’s[coat]chat line repeating forever is the tell) and a glowing one must still glow.
§0-AU — Every coat in the mod redrew (2026-09-09, NOT looked at)
SeededRng never mixed its seed — gap 44
— and now does. That changed every horse the mod has ever generated:
883 of 1056 lines of the pipeline golden, 218 of 623 of the bake golden, and 154 gene icons.
Nothing is expected to look worse, because the same distributions are being drawn
from and only the draws moved, but that is an argument rather than an observation and nobody
has looked at a paddock since.
- A paddock of ordinary horses. The one thing worth eyeballing is whether the population still reads right — the measured share wearing white markings is about two in three (gap 53), which should look like a normal mixed herd and not like a pinto herd.
- Wing cloak is switched off, so there is nothing to look at — and the thing to confirm is the absence: no horse should carry it, it should not appear in the spawn screen’s gene list or in either gene editor, and no carrot should offer it (gap 129). Its files are all still there; it is unregistered, not deleted.
- Quarter. Its quadrant choices come from the new
CHOICEmask rather than a scale-4000 noise trick (gap 102). A quarter horse should show one clean quadrant, and a double-quarter one clean half, with no seam where the two halves meet and no half-strength wash — that last one was a real outcome of the old trick, at about one horse in four hundred.
§0-AT — The night loci, and nine genes repainted (2026-09-09, NOT looked at)
The two night loci are the largest piece of unverified behaviour in the mod: two new AI goals, a supersede rule between two genes, and a sound suppression, none of which has run in a game. The coat changes were all eyeballed as icons, which is not the same as having seen one in a world.
The night loci — behaviour, so nothing here is confirmed by a render
- Does night actually start and stop it? The simplest thing to get wrong. A horse homozygous for any watcher should change at dusk and be an ordinary horse at dawn, and the handler clears its state on the day branch rather than leaving it stale — which is what makes dawn end the behaviour rather than merely stop renewing it.
- Does the watcher actually stand still? The goal claims
Flag.MOVEeven in the two modes that never path anywhere, to stop the wander goal drifting the horse off mid-stare. If a staring horse wanders, that flag is not doing what it is meant to. - Do the two positioning modes work at all?
unseenuses a yaw test rather than a raycast, andbehindpaths to a point derived from the player’s look vector. Both are guesses about how a horse’s navigation behaves when the destination moves every tick, and the plausible failure is a horse that jitters or gives up. - Are the footsteps actually silent? Both
PlayLevelSoundEventshapes are handled because it was not possible to determine from the sources which one a horse’s step takes. If it turns out to be neither, the gene is silent about being silent. - Does the supersede rule read cleanly? Breed a horse homozygous for both loci, stand it in a field with a cow, and check it deals with the cow rather than doing both. Then remove the cow and check the watching resumes.
- Does hunting hurt? Aggression is
setTargeton machinery that already existed, so it should just work — but it has never been seen to.
The nine repainted genes — looked at as icons, never in a world
- The three that lost a ground — coccinella, shieldback, tribal ward. All three now sit on the base coat, so the thing to check is whether they still read on a pale horse: they were designed against a dark ground, and a cream one is the case most likely to look washed out.
- The two whose second allele was rescued — shieldback and tribal ward again. Their “coloured” alleles were identical to their first until the hue knob was pointed at the marking. Worth confirming the two alleles now look like two things.
- Koi’s orange and dark varieties are patches on the coat now rather than a tiling. The icon shows the white variety, which deliberately still covers, so neither of the changed alleles has actually been seen — the only two on this list that were not eyeballed.
- Nyxborn on a chestnut and a grey. The star mask is dark and unsaturated, and a grey drifts through both readings as it ages, so a mid-grey is the interesting case.
- Opossum’s dithered edge is three hard bands at falling densities. On the icon it reads as roan running out; on a moving horse at distance it may read as three stripes, which is the failure worth looking for.
§0-AS — Twelve genes whose masks now stay inside the parts they name (2026-09-08, NOT looked at)
Gap 120 was fixed in the engine, so an inverted
mask no longer paints everything its parts list excluded. Ten
genes changed as a result, and the icons were re-baked and eyeballed —
which is not the same as having seen one in a world.
- The four that were painting the whole horse — webbed, elytra veins, iridescent jewel and opal wing veins. Each was covering the head, muzzle, ears, mane, tail and all four legs at full strength; each now paints only the barrel and neck it declares. These are the ones worth looking at first, because the change is enormous and it is possible one of them was liked that way.
- The three that were partly straying — moth mantle, lace and fracture. Smaller changes: a muzzle, a mane, some ears.
- Koi moved for a subtler reason: its coverage within the declared region changed rather than escaping it.
- Five that gained coverage they had been losing — masked, ehretia, peafowl, snow cloud and war mask. Each had a later mask silently zeroing a part the layer explicitly listed: masked’s “mask over the head and ears” was not reaching the ears, ehretia’s “dorsal stripe from withers to tail” was not reaching the tail. These are small and are believed to be corrections rather than changes, but nobody had been looking at them, so they are the ones most likely to surprise.
- Galaxy and tribal ward are byte-identical to before any of this and need no checking. They are listed because they were briefly broken by the first attempt at the fix, and the fact that they came back exactly is the evidence the final rule is the right one.
The check that would settle it fastest is a side-by-side against the
previous icons: git show HEAD~1:wiki/assets/gene-icons/webbed.png and
friends. The engine change is small and precisely scoped — exactly twelve icons
moved and nothing else did — so anything that looks wrong is a gene whose art
was tuned around the bug, not a regression in the fix.
§0-AR — Fourteen genes, two new masks and seven newly-executed effect verbs (2026-09-08, NOT looked at)
Six of the fourteen have been rendered as an icon and looked at; none has ever been in a world. The eight mechanical loci paint nothing at all, so an icon could not have shown them anything — every claim below rests on code that compiles and on nothing else.
The effect verbs, which are the risky half
Six verbs are new and a seventh (attribute) went from “parsed and
logged once” to actually executing. Each touches a system nothing else in the mod
touches, and each is flagged unverified in its own comment.
- Does an attribute modifier come off again? Spawn a horse with
magic swim speed, swim it, then get it out
of the water — and confirm it is not permanently faster. The apply path only
runs while the condition holds, so nothing but
GeneAbilityHandler.clearAttributesever removes a modifier, and that method has never run. Check the reverse too: two genes moving the same attribute must not strip each other, because the ids are gene-scoped and the sweep only spares ids the horse is currently asking for. - Does the breath accumulator drown anything? Hold a
Shal/Shalhorse under water and aGil/Gilone, and time them against an ordinary horse. The code assumes vanilla clampssetAirSupplyat the top and reads a negative supply as drowning; both are guesses from the sources. A horse that never drowns and a horse that drowns instantly are the two failure shapes. - Does the mob-aura shove actually move anything? Repel is a velocity
nudge plus a cleared target, not a goal — and a pathfinding mob may simply
walk straight back through it. Stand a
Wrd/Wrdhorse in front of zombies at night. Then the other way: aBai/Baihorse should pull every hostile in sight off its rider, which is the one on this locus that could get somebody killed. - Death: the ground and the drops, separately. Kill a
Xpl/Xplhorse (an explosion the size of a creeper’s), aLav/Lavone standing on a floor somebody built (the fluid must refuse to eat it), and aDia/Diaone (diamonds instead of leather, not as well as). Then a horse that is both volatile and diamond-bearing: two loci, both firing, is the cross the split exists for. - The clone egg. Kill an
Egg/Egghorse and use what it drops. The horse that comes back must be a clone — same coat, same name-worthy details, same numbers — and not merely a horse with the same alleles. If the epigenome did not survive the round trip it will look subtly different, which is exactly the failure that is easy to miss. - Milk volume. A
Mlk/Mlkmare should fill several times a day rather than once. Charges divide the cooldown, so the check is that the second filling is possible after a fraction of a day — not that four come at once. Confirm it reaches a water-bearing horse too, which is the whole point of naming a kind rather than a gene. - Combat. A
Gld/Gldhorse should hit measurably harder than an ordinary one, and an ordinary one should now hit for 3 rather than the 4 it used to — the baseline moved onto the gene.
The coat genes, which have been seen only as one icon each
- Nyxborn on things that are not a tobiano
bay. The icon is one horse. What it has to do on a chestnut (nothing much
— a chestnut is neither dark nor white by the chart), on a dominant white
(the whole horse goes black and then stars) and on a grey mid-way through greying
is unverified, and the last one is the interesting case because a grey drifts
through the
whitethreshold as it ages. - Tron in a dark stable. Its tube is an
emissivelayer, so it should hold its colour at night — that is a client render path and the icon baker cannot see it at all. - Ocular from the side, on a moving horse. The eyes are built from four concentric draws off one lattice and they were wrong twice before the icon looked right; whether they still read as eyes on a neck that is turning is a different question from whether they read on a still three-quarter view.
- Shadowcreature’s eyes and light. The gold-eyes-no-sclera path and the level-5 glow are both overlay/ability code the icon does not exercise.
- Stained glass at 25%. The wash is faint by design — it was asked for at exactly a quarter — and on a dark bay it reads as barely-tinted panes. Worth confirming that is wanted rather than a number to raise.
- Bloodstained on a horse with no white at all. On a solid chestnut it correctly does nothing, because a red marking with nothing under it has no bottom edge. On a bay it stains where the black points meet the red. Both were measured; neither was looked at.
The four genes that changed underneath
Fielded, yalia, voided and opalized were moved from asking the pigment to asking the gradient chart. They will look different, and on cream coats they will look noticeably different — a perlino used to read as largely white and now reads as largely cream. Compare them against the previous icons before assuming a regression.
§0-AQ — The 0.2.0 jar, loaded somewhere that is not a dev run (2026-09-08, NOT looked at)
This is the check 0.1.0 exists because of.
implementation project(":common") puts common/ on the
runClient classpath without folding it into the jar, so the 0.0.1 jar
shipped with none of the genetics classes and threw on world load — and
runClient could not have told anyone, because in a dev run the module is
on the classpath either way.
The built jar was opened and listed while cutting the tag, and everything is in
it: the common/ classes, all 85 gene files
(suit.json present, collar.json and
waves.json correctly gone), the 49 breed files, the name tables, the
four structure NBTs, and the assets. ExtremeWhiteDominantGene and
WhiteLockContribution are compiled into it and
PinkHairGene is not, so it is the current tree rather than a stale
build. The packaging bug that produced 0.1.0 has not come back.
What is left is the part a zip listing cannot answer.
- Install the jar into a plain NeoForge 26.1.2 instance —
neoforge-26.1.2/build/libs/, dropped into a realmods/folder, not launched through Gradle. It must reach the main menu, create a world, and load it without a crash report. Being present in the jar and being found at runtime are different claims: the resources are loaded by classloader paths and by the datapack layer, and a dev run resolves both differently from a shaded jar. - Then check the trees separately, because each is read by a different thing and a missing one need not crash on its own: a wild horse must have a generated name (the name tables), a data-driven marking must appear at all (the gene JSON), a breed spawn egg must produce its breed (the breed files), and a stable must generate (the structure NBTs).
- Open the browser with H on the installed jar. Its four tabs read the registry, the roster and this mod's recipes; if the gene bundle did not resolve, the gene database is the tab that says so first.
The release notes on Releases describe roughly a hundred and fifty commits' worth of work, and the great majority of it has never been rendered in a client. Every § below this one is still open. The tag means the suite is green and the jar assembles, and nothing more than that.
§0-AP — The white lock, the reordered paint stack, and a locus that became an allele (2026-09-08, NOT looked at)
Everything here changes where in the stack a marking lands, which means the thing to look at is never one gene on its own — it is two genes on the same horse. The fastest way to see all of it is the spawn egg (or the horse designer, which is the same screen): put a tobiano on a horse, then add one magical marking at a time.
- Extreme white dominant, on a horse that has white and a marking.
extreme_white_dominant=EWD/n tobiano=To/toplus anything loud —magic_zebra=Mzeb/Mzebis the harshest test, because it subtracts 200% from every channel and is designed to read black over anything. The tobiano patches must come out white and unmarked, with the stripes stopping dead at their edges. The edge is the thing to look at: if the lock and the marking disagree by a texel about where the boundary is, it will read as a one-texel fringe rather than as a cut. - And the same horse with no white at all. Drop the tobiano and the marking must be exactly what it is without the gene — a unit test says so at the byte level, but the gene is a rule rather than a painter and a rule that quietly dims things is the failure worth catching by eye.
- Eyes on a locked horse. Blue eyes are deliberately exempt from the lock.
A
kit=W22/N extreme_white_dominant=EWD/nhorse should still have them. - A dhampir that is not a plain white horse. Dhampir moved from priority
135 to 105, so it is now painted under almost everything.
dhampir=Dhmp/Dhmpplus any data-driven marking should read as that marking on a white ground. It used to read as a white horse, full stop. - Suit and hood, which now lose almost every argument. Both were moved to the bottom of the magical band (102, 103) on purpose. Put either on a horse with a second marking and the second marking should win.
- The four modifiers at the top of the order. Fielded, yalia, voided and
opalized were moved to 600+ so they resolve after the markings they read. A
marble_tobianoorpandahorse also carryingopalized=Opl/Oplshould now have that gene’s white opalized, which it could not before.
Three new alleles and two reshaped genes, none of them ever rendered in a client:
opalized=Opb/Opb— the iridescence on the black regions instead of the white. Best seen on a plain black or a bay with strong points. The risk is that the pigment band it reads (0.70–0.88 of the black channel) is wrong for a bay, in which case the cells will land on the mane and legs and miss the body.yalia=Ylo/Ylo— the outline and none of the architecture. On a tobiano it should draw a bright hard line round every patch and add no white anywhere; on a solid horse it must be completely invisible.cleave=Wav/Wav— Waves is now an allele of Cleave rather than a gene, and it is the same interlocking-spear split reversed end for end. Check the two against each other (Clv/ClvandWav/Wav) and that the heterozygoteClv/Wavshows the Cleave side, not both.- Cleave’s half-opaque outline — a soft band on the coat side of the boundary, following the teeth. About two texels wide; if it reads as a blur rather than as an outline, the width is the knob.
- Panda, inside out. White is now a band round the belly plus the neck, head and tail; the shoulder, the butt and all four legs keep the coat. The previous version was the other way round. The panda face — ears, muzzle, eye patches — is kept.
And three wiki surfaces that have never been opened by anyone:
- The paint order — a new page, one long column of every gene that paints, highest first. It asks the mod at run time, so the failure mode is "the whole list is missing" rather than "one row is wrong".
- The punnett square on every gene page. It was an allele × allele grid; it is now two parent pickers and the four foals they can make, coloured by phenotype. Both parents start heterozygous. Worth checking on a locus with many alleles — KIT or the new five-allele Cleave — where the old version gave up and printed a list.
- The landing page’s collapsible sections, with the health genes shut by default, and the LUT lab as a tab on the LUT gene page rather than a page of its own. The lab is the same widget, moved; if it fails it will fail by not appearing at all.
§0-AO — Twenty-four gene fixes, four new painters and a polygenic locus (2026-09-08, NOT looked at)
Owner-driven, off a list of twenty-four notes taken from looking at the horses. Design: the session-log entry. Every gene below was re-baked and looked at from six angles on a contact sheet before it was called done, which catches a gene that paints nothing and catches nothing else — how any of it reads on a moving horse in daylight is exactly what is unverified.
The third pass, and the new page
- Creating a gene is new and has two tab panels, which is the thing to check on it: the Gameplay tab should read as prose for a person and the Coding tab as a reference plus a paste-able prompt. Nobody has opened it in a browser.
- Voided is deterministic now - its lightness knob is gone, so every voided horse with the same markings should share one baked texture. Worth confirming two of them look identical rather than merely similar.
- Circuit’s core and Gudial’s gradient are new per-horse colours: catch or spawn several and check the colours actually differ between lines and are inherited by foals.
- Striped mane and tail gained a coloured allele (
Smc/Smc), which needs spawning - it will not turn up by accident. - Auroraband has no icon and will not get one back until its band stops missing the horse - see gap 108. Spawning a few is the quickest confirmation that roughly one in six wears nothing.
- Invert’s preview window loads now - the cause was TeaVM trapping on the first read of an empty immutable map, which is what an
ALLmask’s parameter map is. Proven by running the wasm itself under node, before and after: it threwremainder by zeroand now bakes the sheet. What is unseen is the picture - open the page and check the horse in the window is a negative (a bay should come out pale blue), and that the other 82 gene pages still draw. - Thirty-two genes arrived in one import and none has been bred. Every one paints and every one was looked at as a baked icon; that is the whole of the evidence. They are the two insect/wing batches - scarab dapple, cracked porcelain, diamond scutes, dragon shroud, duskwing bands, duskfall speckle, ehretia, elytra veins, ink scroll, koi, lace, nebula points, picasso marking, snow cloud, tidemark, tribal ward, wyrmwood sigils, banded socks, beetle pearl, coccinella, dorsal shield, harlequin shield, iridescent jewel, ladybug saddle, moth wings, opaline zebra, painted lady wingmark, shieldback, webbed, wing cloak, moth mantle and opal wing-veins. Each gene’s About this gene section says where its build diverges from the sketch it came from; read that first, because it is the list of things most likely to be wrong. See gap 119.
- The 32 imported genes have never been rendered together. Each was looked at alone, on a bay, with nothing else carrying. Between them they add three new grounds that repaint the whole horse (koi, beetle pearl, coccinella, opaline zebra, moth mantle and shieldback all paint a ground before drawing on it), which is the class of gene most likely to swallow whatever a horse carries below it in the order. Spawn a horse with one of those and a marking gene from the 300s together and check the marking still shows.
- The coat golden file is a run behind. It was regenerated before the thirty-two genes landed, so the next full
:common:testwill fail onCoatPipelineGoldenTestand that failure is expected. Delete it, run, copycommon/build/coat-golden.txtinto place, run again. Gap 118. - The green/pink LUT has never been rendered on a horse. A second palette on the LUT locus (
Grnpnk/Grnpnk), wired exactly as the blue/pink one. Spawn one over a black, a bay and a chestnut - a LUT is read as "red survived" against "black survived", so the three corners of the chart are three different questions - and check the log forcould not load alternate LUT, the failure that renders an ordinary horse and looks deliberate. See gap 36. - Three genes had their baked picture changed and two were moved in the paint order. Flametouched is now photographed as
flamesrather than the embergradient, Patina on a plain bay rather than a tobiano, and Panda’s white band is half again as wide (the body keeps its coat only outside 0.22–0.70 now). Opalized dropped below voided and synort went from the fields band to 104, among suit and hood at the very bottom - which reorders the registry and therefore shifts every horse’s epigenome slots, so every coat in the world is redrawn. The icons say the five look right; nothing has bred one.
Pavonem
- Pavonem was rebuilt to a reference the owner supplied and is the only gene here whose shape came from a drawing rather than from prose. The thing to check is that the middle ring really is bare coat - it is what makes an ocellus read as an eye, and it is the zone that is easiest to lose to another marking painting over it. A Pavonem stacked with anything that covers the barrel is the case to look at.
The preview windows
- Every gene page's preview now offers six base coats, and three pages open on the tobiano rather than the bay — Fielded, Voided and Opalized, because none of them paints anything whatever on a solid horse. Which coat a page opens on is measured at bake time, so the thing to check is that no other page opens on something surprising: the bake prints the list, and it should stay those three.
The second pass, and what it is worth looking at for
The owner reviewed the whole registry after the first pass and sent about thirty notes; those are all applied. Two of them changed the engine again, so the things below are worth a look on a real horse rather than on a contact sheet:
- Five coloured forms drew nothing at all and now draw something — Crescents, Lasertae, Polymoon, Stellar and Wormholes. Each needs two copies of its second allele, so they are not something you will meet by accident: spawn them. Gap 105 is the check that would have caught it.
- The tilted crest band was wrong the first time and is calibrated now (tan 60, not tan 30). It carries Goth's hood, Cosmic's blanket, Collar's upper boundary, Shark's collar and Stars' density falloff. Look at the underside of the neck on all five — that is where the failure shows, and it showed twice.
spreadis a body-space dilation now, which changes Fielded as well as Integration. A wisp appearing somewhere with no white near it would mean it is still leaking.- Integration reads
blackrather thandarkness, so what it grows out of is genuinely the points. On a chestnut, which has no black anywhere, it should show almost nothing - that is the interesting case and it has not been looked at. - Angler's lights are mirrored left to right
through the new
SPOTS mirrorflag. Walk round the horse: the two sides should match light for light, which is the one thing a body-space lattice does not give for free.
The one that changes horses you already have
- A layer whose masks were unioned was being truncated, in fifteen genes.
The mask fold bailed out as soon as coverage hit zero on a
MULTIPLYmask, without checking whether a laterMAXorADDcould put it back — so every union of two regions silently kept only the first. Panda is where it was caught (its hindquarter patch never drew at all), butbrindlelace,cleave,cosmic,dutch,emitola,flametouched,fracture,imperial,marble_tobiano,patina,quarter,stardust,wavesandyaliaall use the same shape. Look at all of them — the ones this session did not otherwise touch are the interesting cases, because their fix is invisible in the diff. Both engines had the same line, so parity was green about it throughout.
The four new painters
WAVES— a band whose edge is a sine, a triangle or a sawtooth. It is the only periodic shape in the vocabulary and three genes now depend on it: Waves' lobed edge, Angler's strings of lights, and Cleave's teeth. Check the lobes are even - that is the whole point of it, and it is the thing noise could never do.CRACKLE— tiling polygons with an even channel between them. Qular is the giraffe built on it. Check the panel edges are straight and the corners meet three at a time; a rounded corner means the warp is too high.SPOTSwith"shape": "heart"— Valentine. A heart is about four texels across at the size it is drawn, so whether it reads as a heart in game rather than on a contact sheet is genuinely unknown. If it reads as a blob, the lever isradiusandspacingtogether.PIGMENTwithspread— Fielded now draws nothing at all on a horse with no white, and grows out of the edges of whatever white there is. The dilation is done in sheet space rather than body space, so it can in principle leak across a UV seam; nothing obvious showed on the bakes, but a wisp appearing somewhere with no white near it on the horse would be that.
Accretion is two loci now
- Accretion decides whether there is a pale field and what colour it is; Accretion Field decides whether it takes the topline or the underside, paints nothing on its own, and is carried by every horse alive. Breed a pair of underside-marked horses and look for a topline foal — that is the observable the split exists for, and it is the only way to tell the new model from the old one from inside the game.
- The
needsblock that makes it work is new format. A gene file naming a locus that does not exist silently never matches, by design, so a typo in a gene key is invisible: if a horse shows the wrong half of a two-locus gene, check the key spelling first.
The rest of the list, briefly
- Thinner and more broken: brindle.
- Moved or extended: collar up onto the neck, cosmic the length of the neck, emitola onto belly and legs, masked over the cheeks, nimbus down the legs, opossum onto the front legs, quazars onto the legs, shark round the base of the neck, yalia down the legs.
- Rebuilt: quarter (it read as a
second nimbus and is now actual quadrants), waves,
patina (whose
PIGMENTthresholds were inverted, so the verdigris was landing on the dark parts). - Goth is on the other edge of the neck. A Y band on the adult neck is
a collar, because the neck is pitched thirty degrees — it wrapped the
throat as readily as the crest. The hood is now a tilted plane. That trick
(
WAVESwith a sawtooth longer than the horse) is used by goth and cosmic and is worth a look on both: it is calibrated to the current pitch and nothing fails if the pitch changes. - Hued pangare is a Java gene now and shares pangare's own region map. Check ordinary pangare has not moved — the shared method came out of its painter, and a bay's mealy underside is the thing to compare.
- Flametouched's gradient form is single-coloured. Whether that is what was meant by “the single-color flametouched” is the one item on the list that was interpreted rather than read; say so if it is wrong.
The wiki, not the game
- Every gene preview window now offers six base coats rather than three — bay, black, chestnut, then a tobiano, splash and sabino bay. The LUT lab reads the same list and gained the same three buttons; it has not been opened since.
§0-AN — Eighty-four magical genes, imported in bulk (2026-09-08, NOT looked at)
The whole of process/ turned into gene files. Design:
the session-log entry. Every
one of them is JSON — no Java classes — and every one has been baked
through the real pipeline as an icon and looked at on a contact sheet, which is
not the same as having been seen in the game.
The icons those eighty-four genes were signed off on were drawn through a sheared projection — the baker's camera basis had an inverted sign, so every part slid up or down the image by its own depth. It still read as a horse, which is why nobody caught it for a day. The bake was fixed on 2026-09-08 (session log) and all 119 icons redrawn, so the sheet is worth another look: a marking that was reported as landing in the wrong place may have been the camera, and one that looked right may not be. The pipeline itself never moved — this was only ever the picture of it.
This is the largest single change the model has ever taken: the registry went from a couple of dozen genes to over a hundred, and every horse in every existing save now has a different genotype code. Saved codes will not parse back to the same horse. That is expected under the no-legacy rule, but it is worth knowing before opening an old world.
Decisions taken without you, that you may want to reverse
| “Speckling colour” is per gene, not shared | Eight of the source markings (Rex, Iuari, Emitola, Gudial, Qhada, Panark, Yalia, Peafowl) describe their colour as the horse’s speckling colour, taken from a separate Speckling locus. A spec gene cannot read another gene’s drawn knobs, so each of these carries its own hue knob instead. Two of them on one horse will not match, and none of them will match Speckling itself. Fixing it properly means a way for one gene to read another’s epigenetics, which is a real feature and not a small one. |
|---|---|
| Paint Moon (G-21) refused |
The akkadorian source’s Paint Moon locus is real-world pinto and roan genetics
— tobiano, frame overo, splashed white, sabino, rabicano, classic roan, grey.
This mod already has all seven as first-class natural genes. Building a magical gene
that re-implements them would give every horse two independent tobianos that know
nothing about each other. Left unbuilt and recorded in
process/akkadorian-z-mutation-genes.md, which is all that is left of
that file.
|
| Everything that changed over time was refused | Per your rule, nothing shifts after the coat is baked. Four sources asked for it and four were refused, each replaced by a value drawn once and kept: Patina (“full expression between 8-10 years”), Opossum (“progressive through the age of a Tharoksu”), Goth (the homozygote “emerges over successive sheds”), and Stardust (“lightening increases with age”). Each horse gets a fixed extent knob instead, so a line still varies; an individual does not. |
| Laciano’s LL disorders refused |
The source gives the homozygote blindness, deafness and annual tail-hair loss, and
says so deliberately. Genes in this import paint and glow and nothing else, so none
of it was built. If you want it, it is a HealthContribution on a Java
gene, not a spec file.
|
| Eye colour is not wired anywhere |
Eleven sources say the gene sets or matches the eye colour — Angler, Aurorae,
Glow, Lantern, Kintsugi, Peafowl, Flametouched, Fawn, Element Dusted, Qhada (“no
pupil”), Laciano (white sclera). A spec gene has no hook into
EyeColor, so none of them touch the eyes. This is the single largest
gap in the import and the most likely thing you will notice.
|
| Valentine’s hearts are round | The source is emphatic that the white markings are heart-shaped. There is no heart mask and adding one is a real piece of work; the gene ships with round spots and the base-colour shift (black to fuchsia, red to pink), which is the half that actually reads at texture resolution. |
| “Inverting” genes only go one way |
Seven akkadorian loci are flagged inverting: they are supposed to flip
the local polarity, so a marking reads light on a dark horse and dark on a light one.
Nothing in the op set does that conditionally. They paint light. The one place the
idea did survive is War Mask, which uses two layers with opposite
PIGMENT masks to come out near-black on a light coat and grey on a black
one — the same trick would work on the others and was not applied for time.
|
| Every white-only gene has a coloured twin | Per your rule: a gene that adds nothing but white carries a second variant allele that paints a colour instead, dominant white over recessive colour, and the coloured allele never gives blue eyes. Thirty-three genes qualify and all thirty-three have it. The line I drew is worth checking: a gene that paints white alongside something else does not qualify, so Corvid (white face, black muzzle), Cosmic (a hue ramp with white stars in it), Winged (white bands on a dark ground), Goth (dark on one copy, pale on two), Striped Mane and Tail (light bundles on dark hair and dark on light) and nine more were left alone. Say the word if you meant those too. Accretion and Quarter each have two shapes already and got one coloured allele between them, since a horse showing the coloured form carries no white allele and there is no second shape left to distinguish. |
Still to verify in game
- The genotype code and the sign. Over a hundred genes now. A pen sign wraps onto three lines and overflows the last one deliberately; with this many genes that last line is very long. Look at a pen.
-
The emissive pass, on a real horse, at night. Eight genes set
emissiveon a layer — Angler, Aurorae, Gamma, Glow, Lantern, Nebula Light and the two example genes. The overlay hook that lights them is new (SpecGene.overlay) and has never run in the game. -
Wild horses should almost never be magical. Founder rates are
derived from each gene’s rarity tier by
process/tools/founders.pyand budgeted so all eighty-four together reach about one wild horse in fifteen. Catch a dozen horses; if more than one of them is obviously magical, the budget is wrong. -
The designer and the spawn screen. Both should now list every one of
these. The designer reads
wiki/horse-designer/assets/genes.json, which is baked; the spawn screen reads the registry directly.
The designer was showing none of them and now should —DesignerApi.mainwas building the editor, which snapshots the gene list, before the page had handed the bundle in. Fixed, the wasm rebuilt, and verified only by reading the call order: nobody has loaded the page since. Hard-refresh it (Ctrl+F5) or the browser will hand you the cachedweb.wasmand the old behaviour. If it is still wrong the console now says so explicitly, naming the count it expected. -
The generated gene pages.
Each gene has its own
wiki/gene-*.htmlcarrying its preview, its inheritance table, how often a wild horse is born with it, and its gene carrot. Served overhttp, every widget on them should work — and the preview now opens on bay rather than black. The family index pages that used to sit over them are gone — the landing page and the sidebar already group every gene the same way — so the thing to check is that a family is still findable without them, from either one.
Known to be rough
- Some genes are visually approximate. Vortex’s four-colour band sequence, Auroraband’s S-curve, Cleave’s interlocking spears and Papillon’s wing are all recognisable rather than faithful — they are built out of noise fields, and a noise field does not draw a specific figure. If any of them matters, it wants either a new mask or a Java gene.
-
:common:testnow takes about nine minutes. It was under a minute. The golden-coat suite composes a full texture per case and every case now runs a hundred-odd genes. Nothing is wrong; it is just slow, and it will get slower. -
The catalogue has saturated.
GenotypeCatalog.size()is nowLong.MAX_VALUE— the product of every gene’s distinct pairs passed 263. It used to wrap to a negative number, which is what the first full test run after this import actually did; it now stops instead. The exact count is still available and exact, as aBigInteger, fromtotalGenotypes().
§0-AM — The three-view wiki, the tabs and the search (2026-09-07, NOT looked at)
Design: the session-log entry.
Gaps 88–91.
This is all wiki, so nothing here needs the game — but it does need the wiki
served over http (python -m http.server), because the
inheritance table asks the mod through wasm and a file:// page is its own
opaque origin.
The split, the tabs, the search, the inheritance widget and the index switcher
were all written and structurally checked — balanced panels on all 83 tabbed
pages, zero words lost against HEAD on all 69 gene pages, the build
and parity green — and then not once looked at. Treat every
item below as unproven, and start with the two that would make everything else
moot.
The two that would make the rest moot
- Does a gene page still render at all? Open
wiki/gene-flaxen.html. Expect the eyebrow, title and lede above a three-tab bar, Gameplay selected, and the page tinted blue. If the tabs do not appear,tabs.jsis not findingarticle.doc’s panels and every gene page is showing all three tabs’ content stacked. - Does the inheritance table fill in? Same page, under “What
you can get”. Expect a 3×3 grid of flaxen genotypes with a phenotype
under each. “Asking the mod…” that never resolves means the new
geneInheritanceJsonexport did not survive TeaVM’s reachable-graph pruning, which would be silent everywhere else.
The tabs
- Do all three tabs switch, and does the page background change with them — blue / purple / green? The tint is the main signal that you are in a different view.
- Does the sidebar re-filter when you switch tab? On Coding it should gain the project pages; on Gameplay it should lose them.
- Does a link into a section on another tab switch to that tab? Flaxen’s
gameplay tab links to
#dosage, which lives on Coding. - Copy the URL after switching tab and reopen it — does it come back on the same tab?
- A gene with more than three alleles — KIT, particle, LYCAN. Expect a plain list of outcomes, not a grid. Particle has forty alleles; if that draws a square, the fallback is not firing.
- A gene with no viewer — any health gene, e.g. PLOD1. Its gameplay tab should lead with the inheritance table rather than a gap where a horse should be.
- Suntouched and
waterborn are worked examples in the
example.namespace, not registered loci, so they deliberately have no inheritance table. Check they do not show a broken one.
The landing page
- Do the three view buttons appear under the stats, and does the hero gradient change with them?
- On Gameplay, the modder and project cards should disappear, and the section headings above them with them. An empty heading over no cards means the section-hiding is not working.
- On Science, expect only the gene pages that have a science tab,
plus the handful of core pages. If a magical gene appears here, its
viewsinpages.jsis wrong. - Click through to a gene from the Science view — does it open on the science tab? That is the whole point of the view being carried in the link.
The search
- Does the slash key open it? ctrl-K? The sidebar box?
- Search flaxen — the flaxen page should be first, not the twenty pages that mention it in passing.
- Search something implementation-shaped, e.g. HorseSkinGeometry, and something real-world, e.g. Morgan. Do the results carry the right coloured tab chip, and does clicking one land on that tab, scrolled to the section?
- The index is 1.8 MB and loads on the first keystroke. Is the first search perceptibly slow on this machine? If so that is worth knowing before it grows further — see gap 90.
The section routing — the part most likely to be wrong
Sections were routed to tabs by a rule over their headings, not by reading them. That is right far more often than not, and it will be wrong somewhere. The default was Coding, so the expected failure is a section sitting on Coding that a player wanted, rather than jargon leaking onto Gameplay. Worth a skim of a handful of pages with an eye for:
- A gameplay tab that is only the viewer, the table and the carrot, on a gene that clearly has more to say to a player.
- Anything on Gameplay that reads like implementation. Health sections in particular stayed on Coding by design — only the one-line health summary from the spec panel was promoted — so a gene whose health story matters may be under-served on Gameplay.
- The lede of each page now shows above all three tabs, so it is doing the job of the plain-language summary. Some ledes are dense and assume the model; those are the ones to rewrite first.
The natural genes with no science tab — resolved 2026-09-09
This section listed 25 pages that the three-view split could not route to Science, because nothing on them was in a section it could move. All 25 now have a science tab and the list is deleted rather than kept as a record of a solved problem. What replaced it — the tabs that predate that pass and are now the thin ones — is on the roadmap, and §0-AY above is the entry that still wants reading.
The two workstations, which cannot both be craftable
cowboy_hitch.json and horsemans_table.json used to be the
same shapeless recipe with different results, so only one of them could ever match
and the other was unobtainable in survival. They now differ along the line
Villagers itself draws between them: the
hitch is rope-heavy (2 hair cloth + 3 braided rope + 2 fences), the table takes the
leather (3 hair cloth + 2 leather + 2 fences).
Craft both. The data is checked by
neoforge-26.1.2/tools/check-recipes.mjs, which refuses two recipes that
occupy the same slot, but no check can confirm that a recipe a player types into a
grid produces the block they wanted. Gap 92.
The item pages
- Eleven new pages under
item-*.html. Their gameplay tabs are newly written rather than moved, so they are the most likely place for a factual slip. The recipes and behaviours were taken from the olditems.htmland not re-derived from the code — worth one pass againstModItems.javaand the recipe folder. items.htmlitself is now a roster of links. Check every row resolves and that nothing that used to be on it has been lost — the gene database stayed on carrots.html on purpose.
§0-AL — Breeds as JSON, breed spawn eggs, and spliced lines (2026-09-07, NOT looked at)
Design: the breed file format, breeds, the two new eggs. Gaps 83–85. The Java half of this is well covered by tests; none of the four things a player actually touches has been touched.
The 49 breeds moved from an 885-line Java class into 49 JSON files. If the
classpath index is not being read, every horse in the world is Feral Mixed and
every other check below is moot. The boot log says
[breeds] N breed(s) registered; the custom spawn egg's
Breed: dropdown is the same answer with names on it.
The breed designer and drop-in checks that stood here moved to §0-CA when both were rebuilt.
The two eggs
- Do filled breed eggs appear in both creative tabs? One per breed
that allows
spawn_egg, in the mod's tab and vanilla's Spawn Eggs tab. A blank one should appear in neither. - Right-click one on the ground. A foundation horse of that breed, placed on the block face, egg consumed outside creative. The tooltip should name the breed, natural/magical, and the commonness tier.
- Custom spawn egg → Make egg. Build a horse, press it, and check the preset egg you get spawns that horse — same coat, same sex, same age, same breed label. This is the one that would be embarrassing to get wrong, because the whole claim is that the egg and the Spawn button are one code path.
- Loot and trades. A breed egg is ~7% of a dungeon chest, and the horseman sells one at Journeyman, Expert and Master. Neither number has been felt in play; the question is whether an egg reads as a find or as clutter.
Spliced lines
- Feed a gene splice carrot and breed. If the allele lands, the foal should be Spliced (Breed) in the info panel. If it does not, the foal is an ordinary one — the carrot is spent either way.
- Breed the spliced foal back to a purebred of the same breed. It should stay Spliced, not revert. That is the load-bearing half.
- Check the cowboy prices it as its base breed and does not count it as part of his purebred string.
§0-AK — Stables that generate with horses in them (2026-09-07, NOT looked at)
Design and attribution: generated stables. Gaps 80–82. This is the least-proven thing in the mod: three buildings converted from formats the game cannot read, placed by worldgen files nobody has generated a world with, and filled by a hook that fires on the wrong event because there is no right one.
/place structure horsegenetics:horse_stable on flat ground in
creative. If the structure does not load, the bake is wrong and everything
below is moot; the error will name a block. Do all three —
stables is the one converted from numeric 1.12 block ids and is by
far the likeliest to have a wrong block in it, and tm_u_stable is
the one with a foreign block substituted.
The buildings
- Does each one look like its screenshot? Compare against the Planet Minecraft page linked on the stables page. What to look for specifically: stairs and slabs facing the right way (the legacy conversion computes those from a data nibble by hand), doors that are whole rather than half, and no floating or missing roof.
- Is anything obviously the wrong block? The legacy table maps only the ids those files use, so a wrong mapping shows as one material in the wrong place rather than as an error. Torches, signs, trapdoors and the stained-glass panes are the fiddly ones.
- TM U Stable's saddle stands should be barrels — that is a substitution for a block from a mod this one does not depend on.
Do they generate
- Do they appear in a fresh world?
/locate structure horsegenetics:horse_stableand travel to it. Then the other two. If/locatefinds nothing, the structure set or the biome tag is wrong. - Do they sit on the ground?
beard_thinterrain adaptation andWORLD_SURFACE_WGprojection; the failure modes are a building buried to its windows or standing on a plinth of air. - Are they rare enough to be worth finding and common enough to find? Spacing / separation are a datapack edit, so this is the cheap knob.
The horses — the part with the most ways to be wrong
- Are there any? The log says
[Stables] filled <id> at <pos> with N horse(s) (S stall, F field found)for every stable populated. If N is 0, read S and F: both zero means the scan found nowhere to stand, which is gap 82. - Horse Stable: exactly seven, four outside and three in stalls. The one stable with a field, and the only one whose split can be checked by eye.
- Are they standing anywhere daft? In a wall, on a roof, in the tack room, inside each other. The scan is a heuristic and this is what would show it up.
- Walk away and come back. The count must not change. If it doubles, the once-only record is not working and every stable in the world is filling repeatedly.
- Arrive from the far side of a big one. TM U Stable is 86 blocks across, so its start chunk may load after the player is already inside; the symptom to watch for is horses appearing around you rather than being there when you walk in.
The genetics each one promises
- Horse Stable — open the i screen on all seven. Every one should carry two rare-or-better natural genes and show nothing at all on the Other genes tab that is magical.
- Stables — every horse Friesian, every horse with at least one homozygous magical trait, and most with exactly one. Finding a stable where they all have four means the ladder is wrong.
- TM U Stable — every horse from the white-marking breeds and none with a magical gene that paints. This is also the best look at whether the white-pattern genes read well on a horse standing still in a lit stall.
- No horse in any stable should have a lethal or be dying. That is unit-tested, so a failure here means something below the stable is wrong.
The extension point
- Does a datapack stable work? The claim on the page is "two files and no Java". Drop a fourth structure in with a JSON beside it and check it generates and fills — that is the only test of the thing this feature was actually built for.
- Does a stable JSON with no structure behind it fail quietly? It should be ignored, not crash.
§0-AJ — Five themed random splice carrots (2026-09-07, NOT looked at)
Design: the five themed splices. Recipes:
items. Nothing here has been through a
runServer boot either — see the note under
§0-AI; this batch adds five items, five models, five
item definitions and five recipes.
Do they exist at all
- Are all five in the creative tab, with names and textures? A
missing model shows as the black-and-magenta cube and a missing lang key as
item.horsegenetics.dilution_gene_splice_carrot. Both are the sort of thing that only appears in game. - Are the five textures actually distinguishable at inventory size, from each other and from the four carrots that already existed? They are one recolour of the plain Unknown Gene Splice carrot, so the risk is that white and dilution read as the same pale carrot.
- Do the recipes work at a crafting table? Unknown Gene Splice carrot plus, in turn, light grey dye, bone meal, an ink sac, a rabbit's foot, an amethyst shard. Note these are not made in the browser's Crafting tab - that grid only makes the paper / known-splice / combine chain, deliberately.
Do they roll what they say
- Feed each to a mare, breed, and read the foal's Genes tab. The spliced locus should be in the carrot's theme every time. Do it several times per carrot — one foal proves nothing about a random draw.
- The performance carrot is the one to hammer. Every foal it touches must come out at or above the baseline on speed, max health and jump — the Health tab colours those green now, so a red one is the bug. It must never roll HMGA2, and when it rolls LCORL it must be the tall/fast copy.
- No themed carrot may ever produce a foal with a disorder, or one short of hearts. This is asserted by a unit test as a subset property, so a failure here means something is wrong further down than the carrot.
- Does the particle burst colour match the carrot? Pale gold, white, brown, blue, cyan.
The bits that go through shared code
- Combine a themed splice with another carrot in the browser's Crafting tab. It should merge like any other — it writes the plain gene splice's token with its theme appended — and the combined carrot should still roll within the theme.
- Feeding one to a foal should still say “a foal cannot be bred” and not consume the carrot's effect.
- Does the unthemed Unknown Gene Splice carrot still behave exactly as
before? It keeps its old token, so nothing should have changed, and this
is the check that the shared
GeneSplicerecord did not break the carrot that already worked.
§0-AI — The My horses table, and the information screen made readable (2026-09-07, partly looked at)
Four things below were checked without anybody meaning to: the owner opened both screens mid-session and reported what was wrong with them, which establishes that the browser opens and its tabs render, that My horses draws rows (they asked what the Barn column was for, which needs rows on screen), that the Breeding preview tab renders, and that the information screen’s Genes and Other genes tabs render with gene rows on them. So the “does the roster arrive at all” gate below is passed and the checks it guarded are worth doing rather than moot.
Three defects came out of that and are fixed but not re-checked:
buttons sitting on top of text (all of them are label-width now), brindle
showing on every stallion, and KIT filed under Other genes on
every horse. Each has its own checklist item below.
runServer could not be booted for this batch either
:common:test, :neoforge-26.1.2:build and
check-parity.mjs are green; the headless boot failed on
DirectoryLock again, which means another JVM was holding
run/world/session.lock — somebody else’s game, not a
registration fault. So nothing here has been through the
“it registers and boots clean” floor, and this batch adds a
payload (horse_roster, renamed from
breeding_roster), five more
(inspect_horse, horse_coat_request /
horse_coat_batch, offspring_request /
offspring_data), a hand-written stream codec and a new AI goal on
every horse. Run ./gradlew :neoforge-26.1.2:runServer once with
nothing else open before anything below.
Sixteen owner requests in one pass, split between the H browser and the i information screen. Design: roadmap § the horse browser, breeding § client sync. Gaps 76–79.
If My horses ever says “asking the
server…” and never fills, stop: the roster payload is not
registering or the request is not reaching HorseRoster, and every
row below is moot. Breeding preview will be empty too, because
both tabs read the same roster; if only one of the two is empty, that is a
different and much stranger bug and is worth saying so.
My horses (browser H, first tab — and it is now the tab that opens)
- Is every horse you own on it? Including one left in another
dimension and one in an unloaded chunk — those should appear with
not loaded in the Where column,
?for bond, and adult regardless of whether they were a foal when you left (that is deliberate; a foal out of the world long enough to unload has almost certainly grown). - Are thirteen columns legible? At GUI scale 2, then 3, then 4.
drawFittedsqueezes a cell rather than dropping it, so the failure mode is unreadable rather than missing, and Name / Breed / Coat / Where are the ones that will squeeze first. - Does clicking a heading sort by it, and clicking it again reverse?
The arrow beside the heading should agree with what the rows are doing. Check
Bond in particular: an unknown bond is
-1internally, so it should sort to one end and not into the middle. - The filter language. Type each and read the count:
mare,foal,-lethal,gen>2,bond>50,breed:shire,gene:SB1,expresses:tobiano, and two together (mare gen>2). Half-typed rubbish (speed>,gene:) must filter to nothing rather than throw — the unit tests say it does, but they are not running inside a render loop. - Does
gene:really find a carrier? The point of the tab. Take a horse you know is heterozygous for something that shows nothing and confirmgene:<token>lists it whileexpresses:<token>does not. - Does clicking a row fill the footer with the two summary lines, and clicking it again clear them?
- Does the coat column say something a person recognises? It is built from the expression names (base coat, then every non-wild coat gene), so it should read like “Bay, tobiano, silver” and not like a list of gene keys. If a horse's column is empty or says something odd, note which horse.
- Refresh re-asks the server; tame a horse with the screen shut, reopen, and confirm it appears (it should, on open) and again after Refresh.
The information screen (i on the horse inventory)
- Is the i button clear of the window? It now hangs off the left edge rather than sitting in the corner. Check it is not off-screen at GUI scale 4 on a small window — that is the one way this move can go wrong, and it would leave no way in to the screen.
- Does the barn-name box look like somewhere you type? It is framed now, and the frame should brighten to blue while the field has focus. This is also the check that the drawing-order fix worked: if the box still looks washed-out and grey, the widget pass is still being painted over and the Done button will look wrong too.
- Genes tab. The full genetic code should be gone; the short form and a count (“12 of 78 loci”) stay. The filter button should read Only what it carries on opening. Turn it off and the list should grow to every locus and the count to all N loci.
- Does the filter keep carriers? On a horse you know carries something silently, the locus must still be listed with the filter on. If it disappears, the filter is reading the phenotype and that is a bug, not a preference.
- Dividers on Coat, Health and Other genes. One hairline between entries, faint. Too heavy and it reads as a section break per gene; absent and the descriptions run together, which is what it is fixing.
- Health colours. Max health / speed / jump green above the baseline and red below, with size left plain. Read the red against the dark panel — it was brightened for exactly this and the check is whether 0.164 is legible, not whether it looks alarming.
The two behaviour changes
- Shift-right-click a tamed foal. Its inventory screen should
open, with no saddle slot and no armour slot, and the
i button should work from it. Then check nothing was stolen:
shift-right-click a foal while holding a breeding
carrot, a name tag, a transfer paper and shears, and confirm each still does
its own thing (the handler runs at
EventPriority.LOWEST, so it should only see a click nothing else claimed). - Does a horse stop wandering while you read about it? Open the i screen on a horse that was walking. It should stand. Then the two failure modes worth provoking: close the screen and confirm it starts moving again within a second or two, and open the screen on a horse you are riding — a ridden horse is exempt and must still steer.
- And the one that would be bad: open the screen, then
/killyourself or alt-F4 with it up. The horse must start moving again within about three seconds (the lease). If it stands there forever, the heartbeat or the expiry is wrong and every horse ever inspected is frozen.
The little horses, and the buttons that were sitting on the text
Everything in this block was built after the owner’s reports, so none of it has been seen — unlike the tabs above, which have.
- Do the row portraits fill in? They arrive a screenful at a time, after the row is already drawn, so the honest expectation is an empty well that becomes a horse a moment later. If they never fill in, the coat request or its reply is not landing and the whole feature is off; if they fill in but the row jumps, the well is the wrong size.
- Scroll the table fast. Each screenful asks for its own rows once; a second pass over the same rows must ask for nothing. The way this goes wrong is silent - a request per frame - so watch for a stutter that gets worse the longer the tab is open rather than for an error.
- Is a foal drawn as a foal? Only in the rows the roster knows are foals, which means only loaded ones - an unloaded horse is assumed grown, deliberately.
- Do the coats match the real horses? Pick a horse you can see standing in front of you and compare it against its row. This is the one check that would catch the coat being drawn from the wrong epigenome, and it is a ten-second check because these are horses you own.
- Breeding preview: portraits in both pickers and the chosen pair above the squares. The pair portraits are drawn at the top of the scrolling pane, so they should scroll away with it.
- No button sits on any text now. Walk all four tabs at GUI scale 2, 3 and 4 and at a narrow window: "Only what varies" beside Refresh (this was the reported one), Refresh on My horses, the filter box, "Craft research paper" on Crafting, and on the information screen the Genes filter and the Offspring Refresh.
Offspring (information screen, fifth tab)
- It should show nothing until you press Refresh, and say so. That is the design, not a failure.
- Are the generations right? On a horse you have bred from: foals under the first heading, grandfoals under the second, a rule between them. Breed a mare back into her own line if you can - each horse must appear once, at its earliest generation, and the tab must not loop.
- Are the descendants drawn in their real coats? These come off the records directly (no second fetch), so unlike the table rows they should be right immediately or not at all.
- Does Refresh on horse A then B show B's descendants? Only one answer is held at a time and it is keyed by horse; a stale answer showing under the wrong horse is the bug to watch for.
Two genes that were being reported wrong
- A plain stallion must have no brindle row. Open the
Genes and Coat tabs on any stallion that does not carry it - the locus
should be absent with the filter on and read
n/Y, “No brindle striping”, with it off. ABrn/Ystallion must still show, and so must aBrn/nmare, which is the carrier the filter exists to keep. - KIT should be under Coat, not Other genes, on an ordinary sabino. Find a near-white or dominant-white horse and check it moves back to Other genes there - that is the outcome that really does claim a blue eye. The particle locus, diet and the cutie mark stay on Other whatever the horse carries.
The Crafting tab, which changed by side effect
- “Craft research paper” is gone from the Gene database tab and stays on Crafting. Check the Crafting one is legible now — it was being painted over by the panel behind it, so it should look like a button for the first time.
- Does the detail pane on Gene database use the space the button freed? It should run 26 pixels further down.
§0-AH — The werewolf locus, rainbow dust, and a particle locus that went recessive (2026-09-07, NOT looked at)
runServer was not confirmed for this batch
:common:test, :neoforge-26.1.2:build and
check-parity.mjs are all green, but the headless boot could not be
run: another JVM was holding run/world/session.lock and
run/logs/latest.log for the whole session, and it was somebody
else’s game. So the usual “it registers and boots clean”
floor has not been checked for the new
lycan_shift attachment or the two new
@EventBusSubscriber handlers. Run
./gradlew :neoforge-26.1.2:runServer once with nothing else open
before anything below.
Three things, and the first of them is by a distance the most invasive change the mod has ever made: it deletes a horse entity and builds a new one, twice a game day. Design: LYCAN, rainbow dust, the particle locus’s new founder table. Gaps 73, 74, 75.
Spawn a Wlf/Wlf horse with the egg, give it a name you will
recognise, /time set night, watch it become a wolf, then
/time set day and watch it come back. If the horse that comes back
has the same name and the i screen still shows
its record and its pedigree, the whole design works. If it comes back nameless
or with a fresh record, stop — the attachment did not round-trip through
the tag and everything below is moot.
The shift, both ways
- Does it shift at all, and within about two seconds of nightfall? The check is staggered by entity id on a 40-tick beat, so a paddock of them should not all pop on the same frame — watch six and see whether that reads as a wave or as a glitch.
- Ride one up to dusk. The rider should be thrown off as the horse goes; the horse should not take the player with it into the tag.
- Take the animal somewhere before dawn. The horse is supposed to come back where the animal is standing, not where it shifted — walk the wolf a hundred blocks and check.
- Hurt the horse to half health at dusk, and check the wolf is at half its own; then hurt the wolf and check the horse comes back hurt. The fraction is carried both ways, which matters because a magic-health horse and a chicken have wildly different maxima.
- Try it on a foal. It should be a baby wolf, and a foal again at dawn.
- Log out overnight, or walk away far enough to unload the chunk. Both entities go to disk together; the horse should still be inside the animal on the way back.
- Take one into the Nether. It should never shift there, and one that walks in already shifted should turn back immediately — a dimension with a fixed time of day counts as permanent day for this gene.
What the animal can and cannot be
- Breed it with a real one of its species. This is the requirement the entity swap exists for, so it has to actually work: two cows, one of them a horse, and a calf. (Then read gap 74 and decide whether it should.)
- Try to ride the rideable ones. A were-pig with a saddle, a were-camel, a were-strider, a were-happy-ghast. All four should refuse, and the refusal should not eat the saddle.
- Try the mod’s own horse interactions on it — a transfer paper, shears, a gene carrot, the i button. All of them should do nothing at all, because there is no horse there to find.
- Shear a were-sheep, tame a were-cat, bucket a were-cod. These should all behave exactly like the real animal. The bucket is the interesting one: a were-cod in a bucket is a horse in a bucket, and nobody has thought about what happens at dawn.
The cloud and the temper
- Does the walking cloud read at all? It is three dust particles round the body on about a third of moving ticks. On a tadpole that may be invisible and on a happy ghast it may be lost inside the model — both are worth a look, because the cloud is the only way to tell a shifted animal from a real one.
- Are two were-wolves different colours? The colour is epigenetic, so two spawned side by side should not match.
- Hit one and walk away. It should follow and strike for three points a second; break line of sight for three seconds and it should give up. Then hit one just before dawn and check the grudge ends with the night.
- Hit a were-chicken specifically. None of the forms has an attack attribute, so the damage is dealt by hand — if any form deals no damage or throws, this is where it shows.
Rainbow dust
- Spawn an
Rbw/Rbwhorse and walk it. Does the dust off the hooves actually read as a rainbow, or as a single colour that changes when you are not looking? The cycle is drawn between 40 and 300 ticks a lap and the slow end is the one at risk. - Spawn several. They should be on visibly different colours at the same moment — the hue is counted off each horse’s own tick count.
- Check the spawn egg’s preview matches. The mote preview in
CustomHorseSpawnScreennow cycles too; if the preview is white and the horse is a rainbow, the preview lost thecycle. - Breed a rainbow horse to a plain one and then the foals together. Half the foals of the second pairing should have it; none of the first should.
The particle locus going recessive
- Count. This is the one that needs numbers rather than eyes: ride a long way and see whether roughly one wild horse in thirteen trails something. The founder table was rewritten from a Hardy-Weinberg spread to a hand-declared one, and a mistake there is invisible except as a population that is all plain or all sparkling.
- Every wild particle horse should be one you can see.
There are no wild carriers any more, so if you catch a horse that trails nothing
and its i screen says
Rflm/n, the table is wrong. - Doubles are catchable now. A wild horse with two particles from one family used to be impossible and is now about one in twenty-five hundred — worth knowing so one does not read as a bug.
- An old horse from before this change may look different. A
Dst/nhorse in an existing world now trails nothing. That is correct, not a regression. - And now a cross-family pair trails nothing either (2026-09-11).
The locus asks for agreement before it draws: the same allele twice, or
two of one family.
Dst/Soulis two carriers and is plain. It used to show the lower-ranked of the two, which made that horse look exactly likeDst/Dst— so a horse trailing dust could be either and nothing told you which. Check the i screen on a bred (not caught) horse carrying two different families and confirm it trails nothing while still listing both alleles. The founder table never handed one of these out, so nothing wild moved.
§0-AG — The horse information screen, the breeding preview, and a mare that miscarries (2026-09-07, NOT looked at)
Four separate things, and the first two deleted the surfaces they replace — so if the new screen does not open, there is no longer any way to read a horse's record in game. Start here. Design: breeding § client sync, breeding § the miscarriage, gap 71.
Get on a tamed horse, press E, and click the i in the top-left corner of the window. If that opens a dark six-tab overlay, everything below is worth checking. If it does nothing, the button could not find the horse — and the grey side panel that used to answer these questions is gone, so say so before going further.
The “i” button and the way in
- Does Done / Escape go back to the horse inventory, and does that inventory still work? The information screen re-shows the container screen it came from rather than closing to the world. Go back and then move an item between the saddle slot and your inventory: if the menu came back dead, that click does nothing. See gap 71.
- Open it on a foal, and on a horse with a barn name and one without.
The six tabs
- Overview — current health against max, speed, jump, size, bond, conditions, and bred / tamed / owner-now. The barn-name box and its Set button are a fixed header that does not scroll; type a name, press Set, close and reopen, and check it stuck. “Owner now” only appears when it differs from the tamer, so a transferred horse is the way to see it at all.
- Genes — the short form, then the full genetic code, then every locus in code order. Copy the full code into the spawn egg: the horse that appears should be this horse. That single check exercises the record, the code, and the egg at once.
- Health — the new one, and the one with no precedent. Each
gene shows its own contribution (
+0.020,×1.42) rather than the total. The question is whether that reads as an explanation of why the horse is fast, or as a column of small numbers. A horse carrying HMGA2 is the interesting case: it moves all four axes and so appears under all four headings. - Coat and Other genes — carried loci only, with the epigenetic values under each. Dhampir is the deliberate oddity: it changes the coat and is filed under Other anyway, because the coat is the least of what it does. Check it is there and not on Coat.
- Family tree — clicking the tab hands off to the pedigree chart. Its Done should come back to the information screen, not to the world.
The breeding preview (browser H, second tab)
- Are your horses in the two lists at all? The roster is every horse the server has on record that you tamed, plus any loaded horse you own now. A horse you were given a transfer paper for is the case that needs both halves.
- Pick a mare and a stallion you know share a recessive and check
the odds read
1 in 4. The arithmetic is unit-tested against ten thousand real draws, so a wrong number here is a wiring bug, not a maths one. - Is the grouping useful? Loci are blocked by the trait they pull
on — Speed, Max health, Jump, Size, Disorders, Coat, then abilities —
with the leopard complex's
PATNmodifiers indented under LP. That is the “group the polygenic ones together” requirement; the question is whether it reads that way. - Toggle All loci. It should go from a readable page to a very long one — that is the point of the default.
The miscarriage
- Breed two MET carriers (spawn-egg
route: add MET to both, set each
met/N). One pairing in four should produce no foal, a chat line to everyone within 32 blocks describing what it looked like, and half a heart off the mare. - The line must not name the gene. If it says “MET” or “embryonic lethal” anywhere, the wrong string is being printed and the whole point of the feature is gone — a player is supposed to work it out from a dozen pairings. The log does name it, deliberately.
- Do the same with the milk locus
(
Watr/Lava) and check the two descriptions are visibly different. - Every successful breeding should also print a few grey
[Breeding]lines in this dev build, and write one line per gene tolatest.log. Grep the log for[Breeding]after a foal: that is the first time the draw has ever been visible.
The spawn egg, in the three places it was blind
- Right-click a horse with the egg. This used to mount the horse; it should now open the editor. Also check aiming at the ground and at open air.
- Switch to survival and open the editor. Everything should work except a Spawn button that reads Spawn (creative only), is greyed, and explains itself on hover.
- Nothing here is a fix for a diagnosed bug — see gap 70. If the third party who reported it is reachable, the useful thing is one line about what they actually saw.
§0-AF — Nine more health genes, and a wild horse that can be sick (2026-09-07, NOT looked at)
The reference’s disorder list is now covered: HERDA, SCID, lavender foal, cerebellar abiotrophy, CVM, GBED and megaesophagus as recessives, plus HYPP and PSSM1 as the mod’s first dominant disorders. Design: the two shapes a disorder comes in.
This is the change most likely to read as a bug when it is working correctly. A dominant disorder has no silent carrier, so if founders could never be affected the allele could never exist — roughly one wild horse in thirty now has PSSM1 and about one in eighty has HYPP. Neither is ever born dying; that invariant is unchanged and tested.
- Find a wild horse with PSSM1 and check the panel says so. The commonest disorder in the mod by a wide margin, and the first one anybody is likely to meet without breeding for it. It should name the condition and show the horse a few hearts down. If nothing in the wild is ever sick, the dominant founder tables are not being reached.
- Breed two HYPP horses. The one locus where the mistake is visible in advance: two affected parents throw a dead foal one time in four, and half the survivors are affected again. This is the whole point of the gene and the quickest way to see the new shape work.
- Does an
H/Hfoal actually die? HYPP is the first gene that is a survivable disorder on one copy and a lethal on two, so the lethal path is reached from a genotype that is not a plain homozygous-recessive for the first time. Quickest route is the custom spawn egg: add SCN4A, set itH/H, pick Foal. - Spawn one of each new lethal as a foal and read the chat line. Seven new conditions, seven new sentences, and nothing has ever printed any of them. Watch for a raw translation key or an empty name.
- Check the information screen's Health tab does not overflow. Sixteen health loci now, up from seven — on a carrier-heavy horse that list is meaningfully longer than anything the screen has been shown. (This used to say “View Genes”; that popup is gone — see §0-AG.)
- Turn the health genetics off in the server config. The two dominants are the new risk here: they are the only disorders that affect founders, so if the config switch misses them a “disorders off” world still has sick wild horses.
- Are the frequencies right in play? The real question, and the only one that needs hours rather than minutes. Carrier rates run 1.2–4%. Too rare and the whole layer is invisible; too common and a paddock of wild horses reads as uniformly broken. PSSM1 at 2.5% is the number most likely to want turning, because every copy of it shows.
§0-AE — Literal epigenetics, drift, and breeds that let go (2026-09-07, NOT looked at)
Epigenetics stopped being one opaque seed per allele copy and became named literal numbers a player can read; every value now takes a tiny drift on its way to a foal; and a breed shapes its founders and then stops influencing anything. Design: the genetics model. Nothing below has been seen in a game.
A given seed makes a different-looking horse than it did, deliberately — the golden coat file was regenerated wholesale. So “this horse looks different from last session” is expected, and is not the bug. The bug would be a horse that looks different from itself across a reload.
- Does a foal look like the parent it took the allele from? The oldest unverified epigenetics claim and still the important one. Breed a strongly marked horse to a plain one, and check the foal's marking against the parent it inherited from rather than against the pair.
- Does a horse survive a save-and-reload unchanged? The one that would be quietly catastrophic. Values are quantised so that what is in memory is exactly what the code string says; if that failed anywhere, a horse would repaint subtly on reload and fork the texture cache. Note a horse's markings, quit to title, reload, look again.
- Spawn a custom horse. This exercises a payload cap that was already too small before this change — the old epigenome code was about 4500 characters against a 4096 limit, so the custom spawn egg may simply have been throwing. It is 65536 now. If spawning works, that bug is closed too; if it throws, the cap is still wrong and the log will say so.
- Open the information screen's Coat tab on a tamed horse
(E, then the i button). The epigenetics readout lives
there and on Health and Other genes now, not in a “View Genes” popup
— see §0-AG. Do the value rows fit? Does the
›marking the expressed copy read as anything? ednrb is the worst case — nine values, one of which is four per-leg numbers on one line. - Cross two extreme breeds — a Percheron and a Falabella. The headline behaviour change. The foals should spread: some large, some small, some in between, depending on which copies they drew. If they all come out the same middling size, a breed standard has leaked back into resolution and the whole point has been lost.
- Is a pure breed still recognisably itself? The other half of the same check. A wild-caught Percheron should still be huge and a Thoroughbred still fast — the band is written onto the founder's copies now rather than re-applied on every lookup, so if founders come out ordinary-sized the write never happened.
- Breed a pair repeatedly and read the numbers, not the horses. Drift is designed to be invisible in one generation, so looking at foals proves nothing. Open the epigenetics readout on parent and foal and compare a value directly; it should differ in about the fourth decimal.
- Does the horse designer still load and draw? It runs
common/compiled to wasm, and the epigenome format changed under it. Paste a code out of the spawn egg and into the designer and check the same horse comes back. - Does the family tree still draw ancestors? The invented-ancestor fallback is deleted, so a record without a stored genome now draws nothing rather than a plausible stranger. Any blank ancestor portrait is a record that never had a genome — worth knowing which.
§0-AD — No horse too slow to escape a zombie (2026-09-07, NOT looked at)
Some horses were resolving to speeds slow enough to be unusable. The genetics are
unchanged — MIN_SPEED is still 0.02 — and
server/HorseSpeedFloor clamps the attribute instead,
at the one place it is written, to vanilla's own slowest horse
(0.1125). Design:
Speed, health, jump & size.
- Race a floored horse against a zombie. The literal test, and
the one the number was chosen for. Breed or find a horse whose panel reads
0.113, ride it, and let a zombie chase you on flat ground. It should pull away. If it does not, the mob and rider movement scales are further apart than they look and the floor wants multiplying up — one expression inHorseSpeedFloor.floor(). - Does the info panel bottom out at
0.113? The panel reads the live attribute, so it should never show less than that however awful the genetics are. - Do the genetics still say the true number? The family tree and
the browser designer show what the alleles resolve to, which for a very slow
horse should still be well under
0.113. If those got clamped too, the floor leaked intocommon/and it should not have. - Do ordinary horses still differ from each other? The floor sits
below this mod's wild-type
0.1875, so the natural range should be untouched and only the genuinely broken horses should have moved. If everything feels the same speed, something clamped harder than intended.
§0-AC — The cowboy, the horseman & transfer papers (2026-09-07, partly looked at)
Confirmed in game: the barn generates and sits on the ground with steps up to it, the cowboy founds and has a face, both posts hand out their jobs, the two share a surname, the horseman keeps vanilla's brain, and transfer papers work end to end. What is new and unseen is the homestead. The house is no longer built at runtime — it is baked into the same structure piece as the barn, and the two work posts moved onto its front step. The piece has since gained a ground course carrying a walk along the front of both buildings, lost the lane that ran between them, and turned the beds round; and the cowboy has gained the ability to open a door, which he has never had before. Those are all changes to a piece the village generator places, so the first question below is still whether the piece generates at all. Full design: Villagers & transfer papers.
The test world tells you where a village is
The “Spawn Test Horse World” button no longer teleports you. On login it
runs the same search /locate structure minecraft:village_plains does and
prints the coordinates plus a clickable /tp. Two things to confirm:
- Did it work, and how long did it take? You should get a grey
[Test world]line naming the village's coordinates, with the/tpin aqua — clicking it should put the command in the chat box, not run it. It aims at y=100, so you arrive in the air over the village and fly down rather than materialising inside a roof. It is a synchronous structure search over 100 chunks, so a noticeable pause on world creation is expected; a long one (or a red “no plains village within 1600 blocks”) means the search radius wants raising, or that seed genuinely has no plains nearby - make a second world before concluding anything. - Watch for a yellow
[Cowboy]line. In a dev build he announces himself when he founds, which happens the moment his chunk starts ticking - usually before you can see the barn. No line means no cowboy in that village, which is expected some of the time (see below) and is the cheapest possible way to tell. If you get one, it carries his coordinates.
Does the barn generate at all?
- Start here, because everything else depends on it.
/locate structure minecraft:village_plains, fly out, and look for a barn and a house side by side at the end of a street, with a walk running down the front of both. Expect them in most plains villages but not all — the piece is three draws in seven at each terminator slot, and at the better part of a chunk square many of those draws lose the bounding-box check anyway. Check three or four villages before concluding it is broken. - Is it appearing less than it used to? That is the risk
the piece took on when the house went into it: the footprint roughly doubled in
depth, the walk has since added a column and a layer on top of that, and the pool
weight went 1 → 3 to compensate by arithmetic rather than by measurement. If
several villages in a row have no barn, the weight wants raising again — it
is one number in
data/horsegenetics/worldgen/template_pool/cowboy_barn.json. - Is the walk flush with the road, or a curb? This is the specific thing the ground course was added for. Standing on the street you should be able to walk straight onto the dirt path in front of the barn's steps without stepping up onto it, and follow it past both work posts to the house's doorstep. A path you have to climb means the lift did not take and the whole piece is sitting a block high. Look for stray dirt too — every path block should still be path. Any plain dirt in the walk means something is sitting on top of it that should not be.
- Are the beds the right way round? Heads to the back wall, feet toward the door.
- Is it at the edge? That is the whole claim of the placement. If it keeps landing in the middle of town, the terminator theory is wrong and the section needs rethinking, not tuning.
- Do the barn and the house sit at the same height? They are one rigid piece now, so terrain that slopes across it will leave one of them cut into the hill or standing on a lip. Some of that is unavoidable and normal for a village; a house buried to the windows is not.
- Two barns in one village is expected occasionally. Only one
should have a cowboy. If both do, the lowest-UUID tie-break in
CowboyHandleris not firing.
Does he open the barn doors, and only by day?
Entirely new and completely unseen — he has never been able to open a door before, so there is no “it used to work” to fall back on. Design: Villagers § He can work a door. Gap: 63. The cheapest test is to stand at the barn in the morning and shut all four doors on him.
- Does he open one at all? He opens a door he walks into, so he has to be heading somewhere through it — his stroll goal is what will eventually take him at one. Give it a minute rather than expecting it on cue.
- Does he open both leaves? This is the one that matters and the one most likely to be subtly wrong. One leaf open is a one-block gap, and a horse cannot use it — so if you see him step through a half-open doorway with the string stuck outside, the partner-leaf lookup is picking the wrong side. Both leaves standing open is the pass.
- Do the horses follow him in? The point of the whole thing. A vanilla-sized horse should manage a two-block opening; anything much over about 1.43 scale will not, and that is gap 55 rather than a new defect — check the size on the info panel before blaming the doors.
- Does he stop after dark? Shut the doors on him at night and he should leave them shut and not stand there shoving. If he opens one, the navigator flag and the goal have come out of step.
- Thunderstorm check, if one happens. He treats a storm as night and will wait it out at a shut door. That is a consequence of sharing the mod's definition of “day”, not a bug — but if it looks daft in play it is one line to change.
- Doors stay open. He never closes one. Expected; noted here so it is not reported as a defect.
The cowboy himself
- Does the whole outfit start outside, in the open, and on the ground? He used to found where the structure put him, with his horses half-inside the walls. He now walks out to a paddock 12–24 blocks away on the far side of the barn from the village bell. The first attempt at that put him on the roof of somebody else's house — the surface heightmap in a village is very often a roof — so a paddock must also be within 3 blocks of the barn's own height with 3 blocks of solid ground under it. Check he is standing in a field, not on a building, and that nothing is clipped into a wall.
- Has he got a name and a herd? Four to ten horses, all named, all with a real breed on the info panel, all with Bred by <his name>. If any reads Feral Mixed, the breed pick fell through.
- Is about half the string one breed? He has a
preferredBreedand roughly half his stock should be it. All-of-one or none-of-one meansCowboyHandler.nextBreedForis not counting what it thinks it is. - Does he restock? Kill or buy a couple of his horses, then leave
and come back. He looks over his string about once a minute and breeds
one replacement per look, up to the number he started with. Over a
longer stay a full string should also quietly turn over — but never while
you are within 48 blocks, so if you ever watch a horse vanish, the
privacy check in
retireOneis not firing.
Two posts, and the house they stand on
The mounted cowboy is gone entirely — no riding, no routine, no barn shelter. A Cowboy Hitch makes the cowboy and a Horseman's Table makes the horseman, and both now stand at the door of a house baked into the same structure piece as the barn. Design: Both of them stand at the house.
- Are both posts at the house's front door, one either side of the step? New: they used to be stacked on the barn. A villager should be standing on each. Both are modded blocks in a piece appended to a vanilla pool, which is the thing that could quietly fail.
- Does the hitch make a cowboy? A yellow
a villager took the hitch and became a cowboyline, within a couple of seconds of a spare villager standing near it. Then place a second hitch 40 blocks away and confirm it takes on another; place one 10 blocks away and confirm it does not, because a cowboy is already within 32. - Does the table make a horseman? The other baked villager should
claim it the ordinary way. This is the only real test of the POI registration and
the
acquirable_job_sitetag merge, so a nitwit standing at the table for ever is a finding, not patience. - Do they share a surname, whichever is hired first? Wade Hargreave and Frank Hargreave. Worth testing both orders — break one of the two barn posts before the world generates the pair, or place a lone table first — because the point of the change is that neither role owns the name. A second outfit across town should be a different family, not a second Hargreave.
- Is the house there at all? This is the headline. The runtime builder is gone — it never once found ground it liked — and the house now arrives with the barn. If the barn is there and the house is not, the bake or the composition is wrong, not the terrain.
- Is the house intact? No jigsaw blocks anywhere in it — one visible in a wall means the bake did not resolve them — and no corner floating. Inside: an interior four blocks across, two beds side by side against the back wall with no stair beside them, and corner posts with bark on rather than stripped oak. Outside: a step up to the front door with a work post either side, so the threshold is not a ledge.
- Do the two chests have anything in them? One either side of the
beds, drawing
horsegenetics:chests/cowboy_house. Expect feed in quantity every time, a lead or a saddle fairly often, and one of this mod's own items now and then. An empty chest every time means the loot table failed to parse, which is logged. Open several before judging the balance — a saddle in the first chest you find is one roll in four, not a bug. - Is there a path between the barn and the house?
dirt_path, the same block the village streets use, running along the front of both and up to each door. - Does the horseman claim one of the beds and sleep in it? Watch him at dusk. He should walk to the house rather than the barn. If he claims a bed elsewhere in the village that is also fine — the point is that he sleeps somewhere.
- Do the horses follow the man? All of them, at a loose distance by day and tightly after dark. He is the herd lead now, so the browser should show them as one herd led by him.
- Is every horse for sale? There is no mount to hold back any more, so the merchant screen should list the whole string.
- Does he behave like a villager otherwise? He should stroll, look
at you, panic when hurt, and do nothing clever at night. He will not go
indoors — he cannot, an
AbstractVillagerhas no villager brain and no schedule, exactly like a wandering trader. That is expected, not a bug. - Do hostile mobs ignore him? New: nothing with the
Enemyinterface can take him as a target. Spawn a zombie next to him at night and watch it walk past; hit him yourself and confirm the zombie still does not turn on him, since retaliation goes through the same door. Between that and ten times health he should be unkillable by accident. - Are his horses still killable? Deliberately — only the man is protected. A wolf taking one should still happen, and the restocking should replace it.
Transfer papers
- Craft a blank (8 paper round a horse hair) and check the tooltip
says Bound to <you>. A blank picked up any other way —
creative tab,
/give— is unbound and should refuse to sign; that is correct, not a bug. - Sign one of your own horses, and confirm it refuses on a horse you do not own.
- Redeem it on a second account, or give it back to yourself. The horse should change owner and keep its breeder. Check the family tree afterwards: attribution must still name whoever bred it.
- Try to tame one of the cowboy's horses the ordinary way — climb on it repeatedly. It must refuse, with a message naming him, and must not rubber-band you: the brand is synced so the client refuses too. If you see yourself mount and then snap off, the sync is not arriving.
- Buy a paper, then walk out and redeem it. Then check he no longer offers that horse — even if you never redeem the paper.
The horseman
- Place a table yourself near an unemployed villager. He needs
no house, bed or custom structure — a profession comes from a job site and
nothing else — so bare ground works. He should take it within a minute; a
villager who ignores it means the POI did not register or the
acquirable_job_sitetag did not merge. - Does a clock promote him? Right-click him with the clock from the debug hotbar: he should go up a tier, his trades should be re-rolled to include the new one, and the trade screen should not open on that click. Five clicks reach Master. If the tier number goes up but the offer list does not grow, the access transformer did not apply.
- Do all five tiers have trades? Clock him to Master and check
each tier offers three. A tier that comes up empty means its
trade_setor one of itsvillager_tradefiles failed to parse — which is logged, so check the server log. - Do the random gene trades produce a real carrot / paper? Buy one at tier 4 and confirm the carrot names a specific gene and actually works when fed. Confirm across a few restocks that no legendary or mythic gene ever appears.
- Saddle and lead at tier 1 — the reason a player walks into a village looking for him at all.
Placeholder art
The blank transfer paper reuses research_paper.png. The cowboy and the
horseman share one overlay,
textures/entity/villager/profession/horseman.png (the owner's recolour
of the farmer hat) over a plains-villager body — check the cowboy reads as the
same trade as the horseman, since that shared file is the only thing making it so.
The cowboy assembles that himself in CowboyOverlayLayer rather than
going through vanilla's profession layer, so the two can in principle diverge:
stand them next to each other once and confirm they have not.
§0-AB — KIT gains the boosters (2026-09-07, NOT looked at)
KIT went from eight alleles to
twelve. The four new ones are the correction the reference asks for: W35,
W32 and W34 join W20 as a group of mild,
viable, additive boosters that between them are most of what this locus does
to a population — W35 is commoner than W20 in the one
large dataset that measured both. W15 joins as the one strong allele with
a homozygote actually on record, and W23 moves from “viability
unknown” to nonviable, which is what its source row says. Every breed with a
KIT table gained booster lines.
- Ordinary markings should be commoner now, and the loud ones no commoner. Spawn a big mixed herd: more horses with a star and a sock, about as many sabinos and near-whites as before. If dramatic white got commoner too, a booster is landing in the wrong branch of the table.
- The ladder must still climb.
W35/N→W35/W35→SB1/N→SB1/W35→W13/N→SB1/SB1→W22/N, each visibly whiter than the last. - Two different boosters must count as two.
kit=W32/W34should render the same asW35/W35— modest white, not minimal. That is the one new rule in the table. W15/W15is a real horse. It should render near-white, and the gallery / catalogue should list it.W23/W23should now be absent, where it used to be the allele the designer opened on.- Spawn a Thoroughbred herd. It got the reference's highest
W20rate (34%) plusW32,W35and a trace ofW5andW22— the breed most of the rareWseries was first described in. It should be the most-marked common breed. - Spawn a Quarter Horse and an American Paint herd. Both carry three boosters and both splash loci now; they are where the stacking should be most obvious.
- Two loci now hand out ordinary markings, and I did not reconcile
them.
SW1at 55% and theKITboosters at roughly 39% carriage are both doing the “this horse has a star and a sock” job, and they stack. Roughly three horses in four should have some white. If that is too many, theKITboosters are the better-evidenced half andWILD_SW1_PERCENTis the number to cut. - Booster frequencies are the reference's ordering at half its
magnitude. Its dataset puts
W35at 0.168,W32at 0.061 andW20up to 0.34 — but it says itself that the sample is horses whose owners paid for a colour test, which is selected for having something to find. I used 0.09 / 0.035 / 0.085 / 0.010. Say if you want the raw numbers. W23changed meaning. It used to be the locus's “viability unknown, therefore allowed” example, atbroad-white. Its source row actually reads all-white or near-all-white with a suspected lethal homozygote, so it is now a strong allele and cannot double.W15took over the “allowed” role and has better evidence for it — an observed homozygote rather than an absence of one.- Three things declined, all for the standing reason. Haplotype
phase (several
KITchanges on one chromosome; one dataset found six across a horse's two copies) is a linkage system, and an allele pair is the model.W34’s possibly-stronger effect on chestnut would cost it an outcome of its own for a “may be”. And the other twenty-odd namedWalleles are one founder each, described in terms an allele already here covers. - Breed booster numbers are my judgement. The reference names
which breeds carry which allele and never how often, except for
W20. Everything else is a plausible number in the shape the reference gives.
§0-AA — the splash loci swap roles (2026-09-07, NOT looked at)
The two splash loci were overhauled against the reference, and the headline change is
a swap: SW1 on
MITF is now the widespread, minimally-expressed allele the reference says
it is, and SW2 on PAX3 is
rare and breed-clustered. SW1/N also gained an outcome of its own,
splash-minimal, painted over a range rather than at a strength.
Every wild-caught horse’s markings changed as a result.
- Spawn a large mixed herd and just look at the markings. Most horses should have modest, ordinary-looking white — a star, a sock or two, sometimes a blaze — and a minority should have none at all. If nearly every horse is bare, or nearly every horse is dipped to the belly, the carriage rate is wrong.
- The same genotype must not look the same twice. Spawn several
mitf=SW1/Nhorses. The point of the range is that one is a snip and a sock and another is a proper blue-eyed splash. If they all look alike the range is not reaching the painter. - Check the ladder still climbs.
SW1/N→SW5/N→SW1/SW1→SW3/N→SW3/SW1should be visibly whiter at every step. - A horse splash at both loci.
mitf=SW1/N pax3=SW2/Nshould be clearly whiter than either alone — that is the whole reason splash is two genes here. Easiest found on a Quarter Horse or an American Paint, which now carry both. - Blue eyes should track the markings, not outnumber them. They used
to come from a locus 90% of horses carried. Now they come mostly from
SW1, and a blue eye should read as a hint that a horse is carrying something. - Spawn an Appaloosa herd. It is the only breed carrying
SW4, at a low rate, on top of its leopard complex. - A Cleveland Bay should still be almost unmarked. The breed standard is minimal white and its table was left deliberately low; it is the check that a breed can opt out of the new baseline.
- The big one: is 55% carrying
SW1the right number? The previous design put a minimal splash allele on 90% of founders so ordinary horses would have socks and blazes. The reasoning was good; the allele was wrong, so it moved toMITF, where the reference actually puts the widespread one. But I also dropped the rate, because the same reference is emphatic that ordinary markings are mostly not splash — no splash allele at all was found in 112 deliberately minimally-marked horses. 55% is a compromise between a defensible allele frequency and a world where most horses have some white. It is one constant,MitfGene.WILD_SW1_PERCENT. - The honest fix is a markings system, and I did not build one.
Ordinary white is polygenic. A small per-horse markings score, drawn from the
shared face-marking vocabulary and running before the white loci, would let
SW1’s frequency fall to what its evidence supports. That is a new system, so it is on the roadmap rather than in this change. - Is
splash-minimal’s range (0.10–0.44) wide enough? The reference’s claim is strong — a singleSW1copy can be indistinguishable from ordinary markings or a classic splash. The low end is a coronet band and a star; the top overlapssplashproper. Widening it further makes the outcome name less honest, narrowing it makes the allele predictable, which is the one thing it is documented not to be. - Breed numbers are my judgement, not the reference’s. The
source names which breeds carry which allele and never how often. I put the
breeds it names at 55–65%
SW1, the ones it does not at 40–55%, and Cleveland Bay at 10% because its standard forbids white. Quarter Horse, American Paint and Lipizzan carrySW2; Appaloosa carriesSW4. PAX3’s page said deafness was not modelled. It was. The code has emitted the shared informationalsplash-deafnesscondition from both loci for some time; only the javadoc and the wiki still said otherwise. Corrected, no behaviour change.- The Mangalarga Marchador is not in the catalogue. The reference
names it for both
SW1and the grey duplication. Worth adding as a breed, or worth leaving out? - Every splash horse’s markings moved. Not just the
frequencies —
WhitePattern.splashnow derives its strength from the same roll that sets the waterline, so even a fixed-strength outcome renders slightly differently. The golden file was regenerated for it.
§0-Z — grey, rebuilt as a copy number (2026-09-07, NOT looked at)
Grey is no longer one G allele and one
progression roll. It is now three alleles — G3
(triplication), G2 (duplication),
N — and the dosage 1–4
picks the progression window, so a N/G2 horse is a steel or mid dapple
grey for life and a G3/G3 is near white. The painter gained a head lead,
an independent mane / tail stage with a root-to-tip ramp, chubari spots, a bloody
shoulder, and a fixed inverted region rule. The gene also emits an informational
melanoma-risk condition. Six new golden cases; nothing seen in a game.
- Line the four dosages up. Spawn a bay with each of
G2/N,G3/N,G2/G3andG3/G3from the spawn screen. They should read as four clearly different horses: steel, dapple, light, near white. If two of them look the same the windows overlap too much. - Check the head really is ahead now. This was an outright bug — the head used to be given a colour-holding boost, the opposite of life. On a mid grey the face, and especially the forehead round the eyes, should be the palest part of the horse. A dark face on a light body is the bug back.
- Dark legs, light body, on the slow greys only. The leg ramp is
scaled by
1 - progression, so aG2/Nshould show coloured lower legs under a grey body and aG3/G3should not. - Look at the mane and tail against the body. They carry their own stage (±0.26) plus a root-to-tip ramp, so some horses should have a mane clearly lighter than the body and some clearly darker, and in both cases the roots should be paler than the tips. A mane that always matches the body means the swing is not reaching the texture.
- Find a chubari. 18% of greys, and only above progression 0.55 - so look at light and near-white horses. They should be rounded white patches, obviously bigger and harder-edged than the dapples. If they come out as slivers, the selector frequency is wrong (that is exactly how manchado's islands failed).
- Find a bloody shoulder. 7%, so this needs a herd. It should be a soft-edged patch of the horse's own base colour over the shoulder — bay on a bay, red on a chestnut — that looks like a stain, not a decal.
- Spawn a Lipizzan herd, then a Camargue one. Grey is heavy in one and fixed in the other; this is the fastest way to see many at once and to check the dapple spacing does not read as a repeating grid across a paddock.
- A grey foal must be its base colour, and must grey on growing up. Unchanged behaviour, but the painter moved under it.
- Read the melanoma flag on a horse. A black
G3/G3should show “highest”, a chestnutG2/N“raised”. It must dock no hearts and draw nothing.
- Are the four windows spread far enough apart, or too far?
They are 0.06–0.52 / 0.28–0.74 / 0.50–0.90 /
0.68–1.00. Overlapping is deliberate — real variation inside a
genotype class is large — but it does mean an unlucky
G3/G3and a luckyN/G2can land close together. If you would rather each dosage be instantly identifiable, narrow them; the table is one constant inGreyCoat. - Is
KEEP_YOUNG= 0.46 dark enough for a “slow” grey? With no age input, every grey adult has to read as a grey, so even the least-greyed one is a long way from its birth colour. The alternative is letting aN/G2look almost like a plain bay with a hidden flag on it, which seemed worse. Say if you want the range to start darker. - Melanoma is reported and never simulated — is that the line you
wanted? The settled call was “melanoma is cut with aging”.
What is built is an informational condition only: a risk tier off the
copy number, raised one step on a black-based coat, with no lesions drawn, no
stat docked and no death. It seemed to be the honest half — it is what
the real DNA test reports — but it is a step past “cut”, so
it is your call. Deleting it is one method in
GreyGene. - Chubari at 18% and bloody shoulder at 7% — too common? A bloody shoulder in life is genuinely rare and slightly legendary; 7% of greys may make it ordinary. Both are single constants.
- The five-stage health pipeline was declined. The reference asked for melanoma susceptibility, then an age-related chance of lesion onset, then lesion burden and severity with health effects. The last two need an age clock and a disease-progression system, neither of which exists, so they are not built and not stubbed.
- G2 is only in the seven breeds the reference names.
Andalusian, Connemara, American Miniature, Mustang, Quarter Horse, Tennessee
Walking Horse, Welsh Pony — plus a small share in the wild pool. The
reference also names the Mangalarga Marchador, which the catalogue does not
carry. Everywhere else greys are pure
G3, so the Lipizzan and Camargue are all fast greys. - The seeds moved again. Grey now draws 1 long + 8 floats where it drew 1 long + 4, so every grey horse from an older world greys differently. Known gap #47.
§0-Y — the midtstol: dun’s two-tone mane (2026-09-07, NOT looked at)
Dun’s mane and tail are no longer flat
points. They now carry a dark band down the centre with pale guard hair either side
— the Fjord midtstol, which is a feature of every true dun and only
famous on the Fjord because that breed clips the mane upright to show it off. Covered
by DunGeneTest and three new golden cases; not seen in a game.
- Look at a grullo and a bay dun side by side. Both should have a near-black centre line down the mane and the tail with visibly paler hair outside it. The bay dun is the one that matters — its mane was byte-identical to a plain bay’s until this change, so if any horse still shows a flat black mane it will be that one.
- Check the tail as well as the mane. The band runs through both (midtstol in the mane, halefjær in the tail) and they should read as one system with the dorsal stripe, not three unrelated dark patches.
- Spawn a Fjord herd. Dun is near-fixed in the breed, so nearly every horse in the herd should show it. This is the breed the feature exists for and the fastest way to see a lot of them at once.
- A red dun should be subtle. Dun barely touches red, so a red dun’s centre line is dark-red-on-lighter-red rather than black-on-cream. Faint is correct; invisible is not.
- A
d1horse must show none of it.d1does not dilute, so its painter is meant to be a byte-for-byte no-op on a black coat — no pale mane edges at all. Ad1horse with a frosted mane means the guard-hair scaling is wrong. - A cream-diluted dun should be the showiest. Pale body, pale guard hair, dark centre. If any horse looks like a photograph of a Fjord it should be this one.
- Is
GUARD_HAIR(0.28) too strong? On a grullo the outer mane comes out around a third of the black the centre keeps, which is a big jump for four texels to cover. It reads as the reference’s “cream, silver-white or yellowish” and it may read as a bug at close range instead. Easy to halve. - The reference asked for a whole new system and I declined.
It proposed a fictional
F“Fjord mane pattern” allele plus three hidden quantitative modifier loci, with the mane stripe visible only onD/_ F/_. That would let a genuine dun show no mane stripe, which the same document says is not how dun works, and it is a new system rather than an existing one. Drawn on every dun instead. Say if you want the modifier locus anyway — the shade / sooty dosage pattern would fit it exactly. - The mane cannot show a true cross-section. A real clipped Fjord mane reads pale-dark-pale across its width when you look at it head-on. The mane box is four texels wide and its two big faces are its sides, so what is drawn is the band down the middle of the side face. From the side — which is where a player looks at a horse — that is the same picture. Head-on it is not, and there is no mesh to fix it with.
- Should the forelock join in? The reference is emphatic that the axis starts at the forehead. There is no forelock box on the vanilla mesh, so the chain currently starts at the crest. The dun face mask is the nearest thing and it is a separate rolled accessory.
§0-X — sunshine and snowdrop (2026-09-07, NOT looked at)
Two new alleles on the existing MATP locus, both found
in 2019: sun (sunshine) and sno (snowdrop). Both recessive,
both rare, and both able to compound with cream. Covered by the golden file and
eyeballed as side views against a perlino and a champagne bay; not seen in a game.
- Line up five pale bays. A perlino
(
Cr/Cr), asno/sno, aCr/sun, aCr/snoand asun/sun. The first four should be indistinguishable - that is the whole point of the alleles - and the fifth should read as a champagne rather than as a cremello, with a pale amber eye instead of a blue one. - The eye is the only visible tell between a sunshine and the double dilutes. Check it is amber and not blue.
- The genome display is the DNA test. Look at a
Cr/sunhorse in the gene browser: it should say double dilute and show one cream allele. In life you would need a specific snowdrop test to learn that, and this is the mod's version of one. - Breed a look-alike pair.
Cr/Crpasses cream to every foal;Cr/sunto half. Two visually identical mares crossed to the same stallion should give visibly different foal crops, which is the gameplay the alleles exist for. - Carriers must be invisible.
sun/Nandsno/Nhorses are ordinary in every way. - A sunshine chestnut and a cremello will look similar, because a chestnut has no black for sunshine to keep and the chart has no gold band (gap #49). A gold champagne and a cremello already collide the same way. Worth confirming it is as close as expected and no closer.
- Are they too rare? Each allele is about one copy in 330, so a homozygote is roughly one wild horse in a hundred thousand and a player will only ever breed one. Faithful (each was found once, in one horse) and possibly pointless.
- Two undocumented compounds had to be decided.
prl/sunresolves to classic pearl andsun/snoto a double dilute. Nobody has ever seen either, so those are the mod's calls rather than facts. - The gallery labels the double-dilute pen
sno/snorather thanCr/Cr, which is an artefact of allele declaration order - and the order is set that way so a genotype code printsCrprlrather thanprlCr. Reversible if the pen matters more than the code string.
§0-W — manchado (2026-09-07, NOT looked at)
A new locus, manchado - the rare Argentine pattern.
Covered by ManchadoGeneTest and the golden file, and eyeballed as side
views beside a tobiano and a leopard. Not seen in a game.
- You will have to breed one. No wild horse is ever manchado - about one in eighty carries a silent copy - so the custom spawn egg or two carriers is the only route. That is deliberate, and it is also the reason this entry is the least likely to get checked by accident.
- The islands are the whole gene. Inside the white there should be a handful of large, rounded base-colour ovals - five to ten, some much bigger than others. If they read as many small flecks that is a leopard; if there are none at all it is a tobiano. Both failures are the same field tuned wrong.
- Top-down. White over the back, crest, upper shoulder and croup; the belly, the underside of the neck, the head and the lower legs coloured. If white climbs from underneath, that is splash's geometry and something is inverted.
- Crisp edges, no roaning. The margin should be a clean line that wanders, not a soft or ticked one. A roaned margin makes it a sabino.
- The tail should be mostly white even though the hind legs are dark - a reported and rather striking manchado feature.
- Stand one beside a tobiano and a leopard. If a player cannot tell the three apart at a glance the pattern has not earned its own locus.
- Is it too rare? Carriers only in the wild, at about 1.2%, and two of them have to meet. That is faithful to a pattern documented in a handful of Argentine horses, and it may mean nobody ever sees one.
- Should any breed carry it? The reference names Criollo, polo ponies, Arabians and Hackneys. Arabians are in the breed list; Criollos and polo ponies are not.
- How much white? The field currently covers roughly the top half of the barrel. Photographs of real manchados vary enormously and some are far whiter.
§0-V — rabicano (2026-09-07, NOT looked at)
A new locus, rabicano - white ticking from the tail
dock and flank forward. Covered by RabicanoGeneTest (including a direct
comparison against the real classic-roan painter) and the golden file, and eyeballed
as side views. Not seen in a game.
- The coon tail is the thing to look at first. It is the hallmark, it is the one feature classic roan never has, and it is on a part of the horse that is easy to forget to look at. Frosted white at the dock, fading down the hairs, with pale bands through it.
- Stand one next to a classic roan. The roan is even over the whole trunk with a dark head and dark lower legs; the rabicano is concentrated at the flank and rear barrel with an untouched head and tail white. If they are hard to tell apart in game the flank field is spreading too far forward.
- Spawn a dozen carriers. The point of the gene is that they do not all look the same: some should be nearly invisible and some obviously ticked. A field of identical rabicanos means the expression roll is not reaching its floor.
- Rib bars should appear only on the well-ticked ones, as broken vertical concentrations low and rear on the barrel - not as painted stripes, and not as a zebra.
- No face white, no stockings. A rabicano must not grow a blaze or a sock; those are the white-marking loci and their absence is diagnostic.
- The two flanks should differ a little. Walk round the horse.
- Rabicano on a roan is a legitimate horse and probably an illegible one. Worth a look to see whether it is interesting or mud.
- Is the ticking fine enough? It uses the same near-binary dither as roan, at a lower frequency, so at 128px it may read as blotches rather than as hairs.
- Should a homozygote be visibly distinct? Right now two copies only raise the floor, with the ranges overlapping most of the way - deliberately, because no dosage effect has ever been demonstrated. A breeder may want a clearer reward for doubling it.
- No breed carries it. It is wild-founder only. Arabians and Quarter Horses are where it is actually familiar, and both are in the breed list.
§0-U — pangaré, and the seal brown's inner limb (2026-09-07, NOT looked at)
Pangaré (mealy) - the pale muzzle, belly and
inner legs - and, with it, CoatRegions.medial, which is the helper
gap #51 asked for and which also gave the
seal brown its fifth soft point. Both are
covered by PangareGeneTest and the golden file, and eyeballed as side
views; neither has been seen in a game.
- An Exmoor or a Fjord herd is the fastest check - both are near-fixed for it, so essentially every one should have a pale muzzle, pale eye rings and a light belly. If a whole Exmoor herd is plain, the breed wiring is wrong rather than the gene.
- A pangaré bay must keep black points. Mane, tail, ears and lower legs stay black while the body underside goes pale. This is supposed to be automatic - if a bay's mane lightens, the gene is working on the wrong pigment.
- A pangaré black must be indistinguishable from a plain black. Stand them together.
- A pangaré chestnut is the brightest version - cream belly, cream muzzle, pale inner legs over a red back.
- The inner legs. This is the new mechanism and the thing most worth walking round the horse for: the inside of each leg should be pale and the outside dark, on all four legs. The medial face is mirrored left-to-right, so a wiring mistake would show as one pair of legs pale on the wrong side - which is exactly the failure a shared helper exists to prevent and exactly the one that is invisible from a single camera angle.
- A seal brown's inner limb. Same check, on a
ShD/ShDbay: the insides of the upper legs should now carry the same tan as its muzzle and flanks. - Sooty and pangaré on one horse is the textbook countershaded animal - dark back, pale belly. Worth looking at because they are adjacent in the order and either could be eating the other.
- A pangaré dun should keep its dorsal stripe and leg bars.
- Is the pale too pale? A strong pangaré belly ends
around
MEALY_RED, which was raised once already because the chart has no gold band (gap #49) and a paler setting came out grey-cream instead of cream. It may still be too far. - How high should it climb? The reference says an extreme
mealy underside "may rise high on the barrel", which is what
Pa2/Pa2does. On a small pony that may be most of the horse. - Five breeds carry it. The reference names about a dozen more (Ardennes, North Swedish Draught, Gotlandsruss, Finnhorse, Noriker, Brabant), most of which are not in the breed list.
§0-T — sooty (2026-09-07, NOT looked at)
A new locus, sooty - the dark countershading over a
horse's topline. It is common, so unlike most of this page's
entries it is not a rarity you have to hunt for: a large fraction of every wild
herd now carries some, and the whole population should look a little different
because of it. Covered by SootyGeneTest and the golden file, and
eyeballed as side views over five bases; not seen in a game.
- Look at a herd first, not at one horse. The gene's job is to stop every bay looking like the same bay. If a field of them reads as one colour the dosage is too weak; if half of them read as black it is too strong.
- The countershading itself. Dark along the spine, fading smoothly to a clear belly. If there is a visible edge where the dark stops, the falloff is wrong.
- A sooty palomino is the money shot. It should read as a dirty bronze horse with muddy lower legs - the most dramatic version because of the contrast against gold.
- A sooty chestnut should be liver, not black. The chart's warm edge is supposed to keep it brown. If a sooty chestnut has black-looking hairs that is wrong, and it is a real conceptual problem rather than a taste one: a chestnut cannot make black hair.
- A plain black must be identical with and without it. Stand
S2/S2ands/sblacks side by side; any difference at all is a bug in the "never past where the texel started" rule. - A sooty dun must keep its primitive markings - dorsal stripe, leg bars, shoulder bar - with the cape drawn around them, not over them.
- Faint sooty against a dun.
S1/sdraws a dorsal haze and nothing else, which is exactly what gets misidentified as dun in real life. Confirm the two are actually distinguishable in game: the dun has bars and a diluted body, the sooty horse has neither. - The mane and tail must not move.
- Is it too common? Roughly two horses in three carry at least one copy. That is what the reference describes ("widely observed, common across domestic populations") and it may still be too much of a good thing when every bay in the world has a dark back.
- Shade and sooty are two loci for one paper. The reasoning is written up, and it is a genuine design call rather than an oversight - but a dark bay can now be dark for two independent reasons, and that may be one reason too many.
- Does the liver-chestnut approximation hold up? Sooty darkens a chestnut by raising the pigment chart's black axis, which on the chart's warm edge resolves brown rather than black. It is the right picture made the wrong way round, and it is worth a look before it is trusted.
- Should a plain black's sooty combination be hidden? It paints nothing there, but it is still a non-wild expression, so a black horse gets its own baked texture per sooty combination - five bakes for one appearance. Cheap to fix if the answer is yes.
§0-S — flaxen, and W4 (2026-09-07, NOT looked at)
Two additions to the colour side. Flaxen is a new locus - a chestnut's pale mane and tail, as a dosage - and W4 is a ninth KIT allele, the Camarillo white. Both are covered by tests and by the golden file, and both have been eyeballed as baked sheets; neither has been seen in a game.
- Spawn a Haflinger herd. The breed is calibrated on this: every one should be chestnut with a pale mane and tail, and they should vary - the point of a dosage is that a field of them is not one colour.
- Does the palest end read as blond or as grey? A near-white
flaxen mane bakes around
#AFA89A, which is a warm cream on paper. In game light against a red body it may read as dirty grey instead, which would be the chart (gap #49 - there is no gold band on it) rather than the gene. - Mane against tail. They are rolled separately and should usually differ a little. If every flaxen horse has a perfectly matched set the offset is too small to see.
- Strand mixing. Up close the mane should keep some darker hairs, not be a flat pale slab.
- Nothing but the long hair. Compare a flaxen chestnut's body, legs and face against a plain chestnut's - they must be identical.
- A flaxen palomino. Cream lightens the body and flaxen the hair; the two stack, and the result should still read as a horse rather than as a white blob.
- Bays and blacks must be completely unaffected, however much flaxen they carry. This is also where the texture-cache change would show if it were wrong: two bays that differ only in flaxen now share one baked texture, so if a bay ever looks like it has a pale mane, that is the bug.
- W4. Spawn a Morgan herd - about one horse in fifty should be
pure white from birth rather than a grey. It should look identical to a
W22dominant white; the difference is only thatW4/W4exists andW22/W22does not.
- Should flaxen be on more breeds? Only the Haflinger and the
Morgan name it, so every other breed horse is
f/fand the whole spread lives in the feral population. The reference names five more breeds (Black Forest, Breton, Frederiksborger, Jutland, South German Coldblood), none of which is in the breed list. - Is the dosage readable? Five bands over a range of four, with a roll narrower than a band. A player breeding two mild carriers should be able to see that the foal came out paler.
- Is one all-white allele enough?
W4andW22are the same horse to look at, and the gene browser is the only place the difference shows until someone tries to breed two whites.
§0-R — the dhampir (2026-09-07, NOT looked at)
A new magical recessive, dhampir. The
genetics are covered by DhampirGeneTest and the golden
file, and the coat has been eyeballed as baked sheets: white, red-eyed, and the red
survives even under the leopard complex. None of the behaviour has been run
at all - three hand-written pieces (DhampirHandler and two
goals) against 26.1.2 sources, and behaviour is the half no test in this repo can
reach.
- Spawn a carrier first.
Dhmp/nshould be an entirely ordinary horse with red eyes and glowing whites - ordinary coat, ordinary stats, eats hay, does not burn. If a carrier burns or refuses food, the homozygous check is wrong somewhere and everything below is moot. - The scleras should glow and the iris should not. Look at one in the dark. A glowing iris reads as a lamp; that is the failure to watch for.
- Then a full dhampir, at night. White, red-eyed, and calm. Check the health bar in the horse screen is about three times an ordinary horse's, and that it is genuinely faster and jumps higher.
- Then let the sun come up. It should start smoking and losing half a heart every couple of seconds, and run - for a tree, a doorway, an overhang or a pond. Water should stop the burning outright.
- The fence. Pen one in the open with a one-block fence between it and shade. It presses jump whenever it is blocked while fleeing, so a strong horse should clear it and a weak one should not. This is the crudest piece of the whole gene and the most likely to look silly - watch for it juddering against the fence rather than jumping, or jumping constantly for no reason.
- The hunt. Hurt one, then put a cow near it after dark. It should walk over, bite once (half a heart of damage to the cow, three hearts back to itself), and then leave that cow alone - it should move to a second animal rather than draining the first. Come back the next in-game day and it should be willing to bite the first cow again.
- It must not bite the player, and must not bite other horses.
- It cannot be fed and does not passively heal. Try every food in the game on it; try leaving it hurt beside hay and water, which heals every other horse in the mod. Neither should do anything.
- Riding. The shade and hunt goals both bow out while it is ridden or leashed. Confirm a ridden dhampir does not fight the player for control - that is the failure mode of a top-priority goal.
- Is the burn rate right? Half a heart every two seconds against triple health is a long, losing argument with the weather rather than an execution - deliberately, so it survives the run to the treeline. It may be far too gentle to feel like a vampire.
- Should it be rideable in daylight at all? Right now the goals stand down for a rider, so a player can simply ride one across a desert while it burns. That is either a nice tension or a bug.
- Should the white be absolute? It is painted absolutely in phase 3, so no pigment gene shows through - but the overlay phase still draws over it, so a dhampir carrying the leopard complex has spots and one with a cutie mark keeps it. That is the same layering dominant white already has, so it was left alone rather than special-cased.
- Other horses are excluded from the hunt. That means a dhampir alone in a paddock of horses has nothing to live on. Intended, or should it bite them too?
§0-Q — the diet locus (2026-09-07, NOT looked at)
A new locus, diet, with twelve narrow diets against an
ordinary wild type. Nothing about it has been run in a game. The
genetics half is covered by DietGeneTest; the feeding half is a new
handler (HorseDietHandler) written against 26.1.2 sources, and every item
id in DietFoods was read off those sources rather than seen in a hand.
- An ordinary horse must be completely unaffected. This is the
first thing to check and the only one that would be a regression rather than a
gap: feed a plain horse wheat, an apple, a golden carrot. Healing, temper, love
mode and bond should all behave exactly as they did yesterday. The handler returns
early for a
NORMALdiet, so it should — but the ordering ofEntityInteractsubscribers is worth confirming rather than assuming. - Spawning one to test. No breed carries a diet allele, so the custom spawn egg is the route: set the locus homozygous for the diet you want. A wild feral-mixed herd carries them at about one in a hundred per diet.
- The refusal. Offer a special-diet horse an apple: smoke, no healing, and a chat line naming what it does eat. Then offer it the right thing: hearts, a horse-eating sound, and the item consumed.
- Buckets and bottles come back. A lava-eater fed a lava bucket should leave an empty bucket in hand; a potion-eater a glass bottle. In creative neither the item nor the container should move.
- Full heals really are full. Hurt a metal-eater badly, feed it one bar of the metal it wants, and it should go straight to full — not heal by some amount.
- Riding and saddling still work. The handler only intervenes for something it recognises as food, but a special-diet horse that could not be saddled would be the worst failure here and the easiest to miss.
- Breeding still works. Golden apples and golden carrots are deliberately let through. Two special-diet horses should still breed.
- Should the diet be visible before you find out the hard way? Right now the refusal message names the food, so the answer is discoverable in one wasted apple. The gene browser also names it outright. Is that too generous, or not generous enough (a tooltip on the horse screen)?
- Is one in a hundred per diet the right feral rate? Twelve diets at 1% each means about one wild horse in eight has one. That is common enough to meet on purpose and rare enough to be a find; it may be too common.
- Is the locus natural or magical? It is declared natural, and its page says why. A lava-eating horse is not natural in any other sense; the flag currently decides only which coat pass a gene paints in, and this one paints in neither.
- Should a narrow diet do anything but healing? It governs healing only. Breeding is deliberately exempt so a special-diet line is not a dead end, and the mod's own gated healing (water + food blocks nearby) is untouched — which means a lava-eater still regenerates in a paddock with hay in it. That may want revisiting.
§0-P — the bay shade overhaul (2026-09-06, NOT looked at)
Bay is a four-band continuum now — blood bay, bay, liver bay, seal brown — driven by a new shade locus plus MC1R and ASIP dosage. Every bay in the world changed, and roughly half of them are now darker than the old constant-body bay. Nothing here has been seen in game; it has been checked as baked sheets and as side views. See agouti and shade.
- Spawn a herd and look at the spread. The point of the change is
that bays vary. Roughly 15% should read blood bay, 61% ordinary, 19% liver, 5% seal.
If a wild field of bays looks like one colour, the band edges in
BayShadeare wrong, not the painter. - The seal brown is the one to judge. It should read nearly black at distance and give itself away up close: a mealy tan muzzle, a paler ring over the eye, and warm light areas low on the barrel at the elbow and the stifle. Stand one next to a plain black. If you cannot tell them apart at all, the soft points are too weak; if the muzzle looks like a painted-on mask, they are too strong.
- The liver bay against the ordinary bay. These are the two adjacent bands most likely to be indistinguishable in game light.
- Diluted bays. A buckskin now has a bay shade underneath it, so a cream over a liver bay and a cream over a blood bay should be visibly different buckskins. Same for dun, silver and champagne. Nothing about the points changed, so if a diluted bay's mane looks wrong that is §0-N's chart, not this.
- A seal brown's soft points are body coat, not points, so a dilution dilutes them. Worth one silver seal brown and one dun seal brown to confirm that reads as intended rather than as a bug.
- The blood bay's muzzle should still be black. The tan muzzle is the seal end only.
- The gene creator's base coats. Its preset list gained
“Blood bay” and “Liver bay” and lost “Bay, low
points”.
base-coats.jsis a hand-port (it always drifts) — check a creator bay against a designer bay rather than trusting it.
- Is a blood bay red enough? The chart's warmest corner at full
red pigment is
#965C3F, so that is the reddest a bay body can physically be —BODY_BLACK_LIGHTis already almost on it. If blood bays should pop, the fix is the chart's warm corner (LUT lab), not a constant inBayCoat. - Should the four bands be named in the UI? They are real
Expressions, so the gene browser and the genome display already say “Seal brown” rather than “Bay”. That is more information than the old model could give and it may be more than you want on a tooltip. - Is 5% seal brown the right rarity? It is set by
ShadeGene's founder table plus the band edges. Seal needsShD/ShDand a dosage term, which is deliberately a find. - The inner limb is not drawn as a soft point. It is a classic
one on a real seal brown; it was left out because the leg boxes' medial faces
need addressing by
Faceand no gene does that yet. Worth building?
§0-O — the shadow pass (2026-09-06, NOT looked at)
Phase 3 now ends with ColorField.liftShadows(SHADOW_FLOOR): no texel a
magical gene painted leaves the phase darker than #151515 in all
three channels, scaled to keep its hue. The composite is a multiply, so a texel painted
pure black scaled the template to nothing and the band lost every strand of hair
shading. See Pipeline § the shadow pass.
- Magic zebra is the one to look at — it is what the pass was
built for, and the only gene whose golden hashes moved (48 of 654 cases, all of them
magic_zebra). Spawn one and look at a stripe up close: the band should carry the template’s strand detail, not read as one flat slab. - Check a stripe against a black horse standing next to it. A magical
black (
#151515× template) is now darker than a natural black (#000000at 80% opacity, so ~20% of the template). That ordering is intended — a stripe should be the darkest thing on the horse — but it is the thing to reject if it looks wrong. - Nothing else should have moved. The pass deliberately skips texels phase 3 did not paint, so natural coats are byte-identical; the golden diff confirms it. If a black or a bay looks different, that is §0-N’s new chart, not this.
- Also in the gene creator.
wiki/gene-creator/js/fields.jsmirrors the pass, so a user gene that subtracts to black previews the same way the game renders it. Worth one creator gene that paints black to confirm.
§0-N — the new default gradient (2026-09-06, NOT looked at)
horselut.png replaced the default chart, so every coat in the mod
changed colour at once and none of it has been seen. The golden test cannot
help here — it composes against a synthetic gradient by design
(gap #48) — so eyes are the only check
there is. Fastest route is the LUT lab, then a herd in game.
- The whole palette is more desaturated. Plain coats bake to
chestnut
#794A33, bay#4C2E21, black#262525. Judge whether the base three still read as the right horses before judging any dilution. - Black horses keep their hair shading. Measured, a black bakes 27
distinct colours across a 0–255 luma spread rather than a flat slab — the
new chart's black corner is
#161515rather than#000000, which is the exact shape of the bug that flattened every bay earlier the same day. The ramp handled it. Worth confirming by eye anyway, on a black and on a bay's points. - The gene creator has its own inlined copy of the chart
(
wiki/gene-creator/assets/textures.js, 256px data URI). It was re-baked; check a creator horse matches a designer horse rather than showing the old palette. - Everything on §0-M below was written against the previous chart and re-measured against this one. The dilution levels did not move; their colours did.
§0-M — the dilutions, set to measured targets (2026-09-06, NOT looked at)
MATP's three outcomes and champagne are set to the owner's restriction targets, measured against the gradient installed the same day. The numbers are exact — verified on a chestnut, where a constant reads back directly because there is no black for the tint term to act on. What nobody has done is look at a horse.
| Outcome | Red restricted | Black restricted | On a chestnut |
|---|---|---|---|
Cr/N single cream | 20% | 29% | #B69679 |
prl/prl classic pearl | 20% | 60% | #B69679 |
Cr/Cr double dilute | 47% | 95% | #DFD3BB |
Ch/_ champagne | 31% | 80% | #C6AF94 |
- Single cream and classic pearl are identical on a chestnut —
both restrict 20% of red, and a chestnut has no black for them to differ over, so
#B69679twice is correct rather than a bug. They separate on anything carrying black: on a bay body#795944against#93745B, on a black#271C18against#563D2D. Worth confirming they are told apart in play, since a chestnut palomino and a chestnut pearl now match. - Champagne is the big visible move — gold champagne is a warm
tan
#C6AF94and classic champagne a chocolate#734833, where an hour earlier they were pale creams. - Double dilute is the only one taking most of both pigments, which keeps it the strongest row however the others move: on a black horse chart 37%,5% against pearl's 7%,40% and single cream's 0%,71%.
- Single cream's red clamps on a black horse.
0.80kept plus a0.30tint is1.10, so a smoky black keeps 100% of its red rather than 80% — the 20% target holds on a chestnut and not on a black. Probably fine, since a smoky black belongs on the chart's red edge, but it is a real divergence and the lever isSINGLE_CREAM_TINT. - Buckskin and amber champagne points sit at chart X 70%, neutral on
this chart:
#2A2823and#A7A399. The amber champagne point is a pale grey against a tan body, a big contrast that may or may not read as champagne.
§0-L — the LUT lab (new, NOT looked at)
A browser checklist. It was a page of its own until 2026-09-08 and is
now a tab on the locus it belongs to:
wiki/gene-lut.html?view=lab. Upload a colour gradient and see the
horses the real pipeline bakes against it — a chart on the left, a spinnable
horse on the right, a base-coat row and one row per dilution locus plus tobiano.
It runs the same wasm the designer does and
draws with the gene creator's mesh emitter and orbit viewport; the only thing it
adds is DesignerApi.setGradient pointed at a file off your disk.
Nobody has opened it in a browser.
file:// will not work
Same reason as the designer and the preview window: loading the wasm is a
fetch. The panel says so itself rather than sitting blank. Serve the
repo with python -m http.server and open /wiki/gene-lut.html?view=lab.
The lab's exact call sequence was driven end to end against the baked wasm in
node, the way §0-J's was, with the PNGs decoded and handed in as the page
hands them. Confirmed: the pipeline accepts its textures; the three bases come
back Black / Bay / Chestnut; all six gene keys resolve and yield buttons
(Ch/Ch; d1/d1, D/D; prl/prl,
Cr/N, Cr/Cr; Mu/Mu; Z/Z;
To/To); all six stack onto one genotype; a stale gene key reports
missing and a bad allele token refuses. The load-bearing one:
swapping the gradient really does redraw every horse — a
synthetic 64×64 chart moved 4 791 texels on the dilution-stacked horse and
11 776 on a plain bay, an odd-sized LUT is accepted (GradientLut
normalises), and going back to Natural is byte-identical.
The footprint overlay was checked the same way, across all three bases and eight combinations. It agrees with the model everywhere it was asked: black lands bottom-left (red 100%, black 100%), chestnut top-left, champagne on a chestnut at chart X 45% and cremello at 92%, mushroom on a black at 88%/100%, dun spreading over 29 histogram cells where a flat dilution occupies one, and a tobiano reading the chart at 4 160 texels against a solid black's 11 904 - white is off the chart rather than a colour on it. Bounds stay inside [0,1] and no cell index exceeds the bin count.
What has not been looked at at all — everything visual
- Does it come up? “Loading the coat pipeline…”, then a two-column panel: chart left, horse right. On a narrow window the columns stack (860px breakpoint) — that media query has never been rendered.
- Is the chart the right way up? The three corner labels are positioned by CSS over the canvas and claim chestnut top-left, white top-right, black bottom-left. Compare against the art. If they disagree, the labels are wrong, not the pipeline — but a mislabelled axis on this page would send someone editing the wrong corner of a gradient.
- The rotated Y-axis caption (“more black pigment”) is
a
rotate(90deg)with aright toporigin. Most likely thing on the page to be sitting somewhere silly. - Does the hover readout track the cursor? A swatch and a hex should follow the mouse across the chart and reset on leave.
- Both upload paths. The “Upload a LUT…” button
and dragging a file onto the left panel (which should highlight while dragging).
Each should add a button marked
▲, select it, and update the size line underneath. Dropping several at once should add several. - Does the horse visibly change? Proven in the bytes, not in the canvas — the texture upload path through three.js is the untested half.
- The two shipped buttons, Natural and Blue / pink, and switching back and forth between them and an upload.
- Stacking. Champagne on cream on dun should be one horse, and the caption under the viewport should list every active token.
Cr/prl, the dashed button. It should look identical toCr/Crapart from the eyes — and the eye is a 2×2 block on a 128px sheet, so it may not be visible at all at normal zoom. If it is not, that is expected and the note on the page explains it.- The dice rerolls the epigenetics and should move the tobiano patches without changing the colours.
- The footprint overlay — the numbers are proven, the drawing is not. The chart should dim everywhere the horse does not sample and show the art through where it does; a dashed box round the range; solid bars on the bottom and right edges; a white crosshair at the centre of mass. Check the crosshair lands where the centre of mass line underneath says it does, since that is the one number tied directly to a mark on the canvas.
- Does the overlay track? Switching
Ch/ChtoCr/Cron a chestnut should walk the crosshair from 45% to 92% across the chart. Unticking Show what this coat reads should leave the bare gradient with no residue. - A fully white horse (stack enough white) should say “no pigment anywhere” rather than drawing a box round nothing.
- Click the chart. An amber mark should pin exactly where the pointer was — check it lands under the cursor and not offset, since the canvas is drawn at a different size than its backing store and that is where a click-mapping bug would show. The panel should then give red / black pigment left and restricted.
- The colour box. Type
#B0A08Aand press Enter; a mark should appear on a plausibly matching part of the chart. Try a colour the chart cannot have (#00FF00) — it should warn that the match is a long way off rather than pinning a confident point. Junk (nonsense) should say it is not a colour. - The two marks together. Amber (clicked) and white (centre of mass) should be distinguishable where they overlap, and the amber one should survive on a pale corner of the chart — it is drawn with a dark halo for that reason.
- What “Natural” actually is. It reads the designer's
copy of the gradient, which is currently out of sync with
common/— see gap #48. Until that is re-baked, the button is not showing the game's gradient.
§0-K — the gene-carrot recipe card (new, NOT looked at)
A browser checklist, and it is on every gene page,
under a new Its gene carrot heading above the see-also block. wiki/gene-carrot/ draws the Known Gene Splice
recipe as a 3×3 grid (horse hair, this gene’s research paper, a
golden carrot, the rarity item) plus what feeding the carrot does, and asks
the mod for everything that varies per gene. Same wasm as the preview window;
the two share one load. Nobody has opened it in a browser.
The export was driven over every gene page against the baked wasm: each
page’s data-gene resolves to a registered gene (the two
that do not, suntouched and
waterborn, are example.*
spec genes and were deliberately left without a card); the loci with no
carrot come back saying so rather than drawing an empty grid, and the loci
outside the Unknown splice pool are marked. It also turned up
gap #43: every gene is the default
tier, so every card prints the same price.
- Does the grid read as a crafting grid? Four filled cells top-left, five dashed empties, an arrow, the result. The two cells that are this mod’s own items are tinted green — that is the house rule (at least one modded ingredient) made visible. No item icons, on purpose: the vanilla textures are Mojang’s and not ours to ship, and half a grid of icons beside half a grid of text would read worse than text throughout. Worth a second opinion on that call.
- The no-carrot pages. Sex, extension, agouti, LUT and the recessive disorders should each show the note rather than a recipe.
- Two widgets on one page. Tobiano
is the only page carrying both the preview window and the card. They must
load one wasm between them (
HG.java.load()is memoised) — if the page fetchesweb.wasmtwice, that memo is not working. - Does it fit at the bottom of the article? The card sits above the see-also block. Four pages (brindle, cutie mark, LUT, tiger eye) have no see-also block at all, so on those it is the last thing on the page.
- Narrow window. Under 620px the result wraps under the grid and the arrow turns to point at it.
§0-J — the gene preview window (new, NOT looked at)
A browser checklist. It is now on every gene the
horse designer says it can show a coat for — the designer's own
showsAs classification, so the ability, stat, size and condition
loci are deliberately left without one. Tobiano
is the one that has been looked at; the leopard
complex and KIT are the two worth looking at
next. wiki/gene-preview/ is a drop-in window that
shows one gene on a black, a bay and a chestnut, as a horse
you can spin, with a dice in the corner that rerolls the epigenetics. It runs
the same wasm the horse designer does,
draws with the gene creator's mesh emitter and its orbit viewport, and adds
only the three buttons and the wiring. Nobody has opened it in a
browser.
file:// will not work
Same reason as the designer: loading the wasm is a fetch.
Every gene page carrying a preview joins the designer in being
un-double-clickable. The window says so itself rather than sitting blank.
Serve the repo with python -m http.server and open
/wiki/gene-tobiano.html, or read it on the published wiki.
The new exports were driven end to end against the baked wasm in node,
with the four PNGs decoded and handed in exactly as the page hands them:
the three bases build the genotypes they claim to
(E/E a/a, E/E A/A, e/e a/a),
tobiano offers the one outcome the model says is distinct
(To/To — the heterozygote paints the same),
KIT offers one per white outcome without the page knowing
anything about KIT, a stale gene key and a bad allele token
both come back as a refusal rather than a plain horse, and the coats bake
with white patches over each of the three bases and move when the
epigenome is rerolled. EDNRB’s O/O resolves
the lethal-white condition the window puts in its footer.
What has not been looked at at all — everything visual
- Does it come up? “Loading the coat pipeline”, then a bar of three base buttons, a horse, and a footer. It pulls three.js and OrbitControls off a CDN and the wasm off this site, so the first paint is not instant.
- Black, Bay, Chestnut should each change the coat under the same white patches — the patches are the epigenome's and must not move when the base changes. The dice is the only thing that moves them.
- Drag to spin, scroll to zoom. Panning is off on purpose: an article is not a workspace. Check that a scroll over the horse zooms rather than scrolling the page past it — and, more importantly, that a scroll beside it still scrolls the page.
- The dice rerolls epigenetics only. The horse is the same horse: same genotype line in the footer, different patches.
- Does it sit in the article? It is meant to read as a figure in the page, not as an embedded tool — it borrows the wiki's own colours. 340px tall, 250px under 700px wide.
- The outcome row. Tobiano has one outcome, so it is a label rather than buttons. The row becomes a button group on a gene with more than one distinct look — KIT shows seven, Light six. That path has never been seen in a browser, and it is now on most of the pages.
- The modifier strip, which only
the leopard complex has: a row for
PATN1and a row forPATN2under the main bar, each starting at off. It exists because leopard's ownexpressionOfanswers “varnish roan” for everyLPhorse and the real pattern is one of eight. Offline, the window reaches every distinct look in the page’s own table — what wants checking is that they look like mottled, leopard, blanket, snowcap and the rest, against the table on that page.PATN1andPATN2have no pages of their own and get no window; they are reachable here instead. - Genes that do nothing on one of the three bases. Several are correctly invisible somewhere and it should read as informative rather than broken: mushroom dilutes red and does nothing on a black, dun’s primitive-markings-only allele draws a black stripe on a black horse, agouti is invisible on the bay base (which is agouti) and on a chestnut, and extension is invisible on the chestnut base for the same reason. That is what three bases are for.
- The footer condition chip. Unexercised on Tobiano, which has no conditions. It is the reason to put the second preview on EDNRB.
One page carries it. Rolling it out to the rest of the coat genes is deliberately waiting on somebody actually looking at this one.
§0-I — the horse designer (new 2026-09-06, NOT looked at)
A browser checklist. wiki/horse-designer/
is the browser twin of the custom horse spawn egg: the same
gene list, the same click-to-add, the same right-hand column, over a horse
walking a grass field. It runs common/ compiled to WebAssembly
by TeaVM — not a port, the actual bytecode — so all
48 genes are live and the coat is byte-identical to the
game's. Nobody has opened it.
file:// will not work
Loading the wasm is a fetch, and a local file is its own
opaque origin, so the browser refuses. Use the published wiki, or serve
the repo: python -m http.server from the repo root, then
/wiki/horse-designer/. This is the one page here that is not
openable by double-clicking, and the gene creator is unaffected.
The compiled Java produces byte-identical coats to the JVM
— the same class run three ways (JVM, TeaVM JavaScript, TeaVM
wasm) gives twenty identical coat digests across genotypes reaching every
painter. The exported API was exercised end to end in node: 47 gene rows,
50 breeds, adding agouti reads back as “Bay”, and brindle on a
stallion snaps to Brn/Y rather than the impossible
Brn/Brn. The GUI was driven headlessly against that same
wasm — every right-column button fires its method, a gene row adds,
KIT’s eight alleles open a dropdown and a pick lands.
Every file the page requests serves with the right MIME type, wasm
included.
Parity with the spawn egg — the point of the page
Open both and compare. They should be the same screen:
- The gene list. Every gene alphabetically by display name,
the sex locus absent. A gene off the horse is a plain name; clicking it
adds it and it grows two allele buttons and an
x. An expressing row is green with its outcome underneath; a silent one is grey and says “no effect”. - Adding a gene picks the allele that does something —
homozygous where the horse can carry it.
KITshould not come in atW22/W22: the strong dominant whites are nonviable homozygotes, so it picks the strongest allele that can double. - More than three alleles gets a dropdown, three or fewer
cycles. So particle,
KIT,ACANandMITFdrop down; everything else cycles. - The right column, in order: Age, Sex, Breed, Randomize + its arrow, Add random + its arrow, Rnd health, Clear genes; then, at the foot, Make egg, Copy horse / Paste, Spawn, Cancel.
- Sex-linkage. Add brindle, switch to Stallion: it must
snap to
Brn/Y. Switch back to Mare and the placeholder must go. - The short form and the epigenetic fingerprint under the list should match what the spawn egg shows for the same horse. Export here and Paste into the spawn egg in game — that is the sharpest test there is, and the two horses should now be identical down to the epigenetics, which a genotype code never carried.
Two divergences are deliberate: where the spawn egg has Spawn and Cancel there is nothing to spawn, so those slots are Wander and Reset view.
The name, the export, and the field
- Every horse is named. The name is the header, in two halves: click either half to reroll just that one, or use Reroll name in the right column for both. Picking a breed or hitting Randomize renames the horse, because it is a different horse.
- Export and Import round-trip a horse file — two code strings plus a readable summary. Export one, Randomize, then import it back: name, sex, breed, coat and the epigenetic fingerprint should all return exactly (that round-trip passes offline against the compiled wasm; what is unchecked is the file picker and the download in a real browser). Import is tolerant on purpose — an unknown gene drops, an unrecognised breed loses only its label, and it says which. The custom horse spawn egg now reads the same format off the clipboard (Paste), so exporting here and pasting in game is the route across — unplayed, check it.
- The wiki's own gene lists. The sidebar and the landing
page are now generated from the registry and grouped by the same
families as this menu. Worth one look on the published wiki: every
registered gene with a page is in both lists, which makes each of them
long. If the grouping reads badly, the fix is one table -
common/genetics/GeneFamily- and not the pages. - Every gene page opens on a bay. The preview window
already did; what changed is that
BaseCoats.all()now offers bay first, so the button order is Bay / Black / Chestnut and the LUT lab opens on a bay too. Check a dark-marking gene - Voided, Goth, Magic zebra - actually shows something the moment its page loads, which was the point. - The gene-family menu above the list. Pick Natural dilution genes: the list should drop to seven rows and the scroll bar should go away. Pick Magic: lines and strokes and it should be the fourteen stroke genes. All genes restores it. The filter is a view only — a gene filtered out is still on the horse, so the coat must not change when you change the menu.
- The padlocks. Lock KIT at a white pattern you like, then hold Randomize: the pattern and its epigenetic fingerprint stay while everything else moves. Rnd epigen. must respect the lock too — that is the half most likely to be wrong, because the epigenome is rebuilt whole and the locked loci are put back into it.
- The Randomize menu. Eleven modes; the ones to actually
look at are True random (should produce absurd horses, and never
an impossible one — no KIT
Whomozygote, nomet/met), Rnd dilution and Rnd white (should visibly change one thing and leave the rest of the horse alone), and Rnd +3 magic (should always land three magical genes that are actually showing, not three that happen to be silent). - Sex is rolled first. Add brindle (X-linked), then hold
Randomize. The row must never sit in a state a horse of that sex cannot
carry — no
Brn/Brnstallion. - Rnd health, off by default. With it off, no amount of randomizing should ever put a disorder or a stat gene on the horse. Turn it on and they should start appearing. This one is worth checking in game as well, since it is the switch that decides whether Randomize can hand you a lethal.
- Extension, agouti and shade should be on the horse the
moment the screen opens, and have no
x. Clear genes must leave them there. - Does it open at all? A boot overlay, then sky, grass, a horse, and the panel over it.
- Is the horse in the gap? The camera is shifted sideways so the horse frames into the space between the two panels rather than behind the gene list.
- Does it stay near the block? The wander is pulled toward the reference block — the further out it strays the narrower the spread of headings it will pick, so it should circle the block rather than leave. It must also never spin on the spot indefinitely: a turn now resolves into a walk when it reaches its heading, which the old fixed-duration spin did not.
- Is the ground still too bright? The grass texture is
multiplied down by
GROUND_TINTinscene.js- one constant, easy to re-tune. The horse's own lighting is untouched. - The player beside the block is a scale reference: vanilla proportions at the renderer's 0.9375, so ~1.89 blocks tall against the cube's 1.0 and an adult horse's 2.11 to the ear tip. Untextured on purpose - the default skin is Mojang's asset, not this repo's to ship. Its hair used to z-fight its scalp and now wraps it; confirm there is no flicker on the crown as the camera moves.
- Controls. Drag the empty middle to spin, WASD and QE to move, scroll to zoom. A drag on a panel must not spin the horse, and scrolling over the gene list must scroll the list, not the camera.
- Size renders correctly. Add
LCORLor the magic body-size locus and the horse should visibly change against the one-block reference cube, with thesize 1.14xreadout under the preview — the same readout the spawn egg draws. - The gait is an approximation and is not a port of
setupAnim. Worth an opinion on whether it helps or distracts.
What it still cannot show — and says so
12 of the 47 rows are struck through. Clicking one still
adds the gene (it is real, and it belongs in an exported horse); the row
says “not shown here” underneath, and the reason goes to the
console. Which genes those are is
derived, not typed — DesignerApi.showsAs
asks each gene whether it paints, moves the horse’s scale, declares a
condition, or is read by a painter, so a gene added later classifies itself.
Worth checking the split still reads right:
| Verdict | Genes | Struck? |
|---|---|---|
coat | 26 — everything that paints, plus PATN1 / PATN2, which paint nothing themselves but are named in the leopard complex’s coatDependsOn() | no |
size | 6 — ACAN, B4GALT7, HMGA2, LCORL, SHOX, magic body size | no |
condition | 3 — PLOD1, RAPGEF5, ST14 (the condition is named in the panel’s condition line) | no |
ability | 4 — cutie mark, particle, milk, verdant. Item icons, particle types and world blocks: nothing outside Minecraft to draw them with | yes |
stats | 8 — CKM, MET, MSTN, PDK4, RYR2, magic speed / health / jump. Real and invisible; the figures ride along in the JSON export | yes |
Also not drawn, on genes that are otherwise fine: emissive / glow texels (light’s gold mane paints, but does not shine).
There are no toasts any more (removed 2026-09-08, owner’s call — they did not reliably clear themselves and a run of Randomize clicks buried the horse behind them). Check that nothing important went with them: a failure to load the mod should hold the boot overlay up and say why, an unreadable horse file should raise a dialog, and everything else — lethal conditions, genes the page cannot draw, an export — should be in the browser console and, where it matters, on the panel already.
§0-H — the gene creator (rebuilt 2026-09-06, partly owner-verified)
“That looks correct.” A general confirmation off
the live page, not an item-by-item walk — so it closes the three things
you cannot miss on opening it: the page loads at all (the
expresses ReferenceError is gone), the
parity line reads green, and the 3D preview
reads as a horse instead of the pile of bounding boxes it was.
What a look cannot confirm is everything you have to interact with. Still open:
- Typing. Every edit used to re-render the panel and destroy the focused input, so a text field took one character per click. Type a few words into Display name, the blurb and a layer name — the caret should stay put.
- The Gameplay section (left panel, under “What it does”): blurb, rarity, the gene-carrot toggle with its one-copy / two-copies choice and flavour-item list, and the optional splice table seeded from the founder shares. Everything left at its default should stay out of the exported JSON — watch the Export box as you change them.
- The Effects section (right panel, under Layers): add each of
the eight verbs; check the trigger picker grows a ticks box for
intervaland an item box foron_interact, and that “Only when” builds a flag list. Then load the shipped Waterborn or Suntouched file and confirm its effects come back intact. - Clicking the horse. The pick path goes UV → texel → the pipeline’s own sampler. A round-trip over every face of both meshes passes offline; confirm by eye on a leg and on the barrel that it names the part you clicked.
- Foal framing. Switch Age to Foal: the camera should re-frame, the foal should stand on the grid, and it should be neither clipped nor lost in the distance.
Owner’s note on 2026-09-06: it wants a usability pass next — see roadmap §9.1. Also still unchecked anywhere: how it behaves with no connection, where three.js does not load and the page falls back to the flat sheet (which is still a real bake).
§0-G — this session’s work (built 2026-09-06, NOT play-tested)
Six changes, none of them seen in the world. They are listed most-worth-looking-at first.
The white recalibration — look at a herd
Both white painters now measure against the topline
(bounds(skin, Part.BODY).yMax()) on a convex ramp, instead of against the
whole-horse box. This is the biggest visible change in the session because
PAX3’s SW2 is on 90% of
founders — it changes what an ordinary horse looks like.
- Does the ladder still read as distinct steps? Bold splash should be past the elbow and onto the barrel (measured 95% legs, 31% belly); extensive should be nearly everything below the topline (100% / 100%, 11% back).
- Do the two splash loci still visibly stack? The stacking signal
is saturating now (
w / (w + 0.10)). AnSW1/N+SW2/Nhorse should read as a bold splash, not as a slightly whiter minimal one. - Does a splash allele on a tobiano still leave a tobiano? That is the case the saturation exists to protect — it must not go near-white.
- Sabino’s belly patch is anchored at the underline now.
A classic
SB1should reach the underline and a hand up the flank, and even sabino-white should keep a coloured topline.
Not fixed, and still open above: tobiano’s
cover knob, which is still calibrated as if the patch field were
uniform. Both are fixed now — the same two-pass quantile in
both genes. Frame’s band is rebuilt (§0-F2) and
tobiano’s calibration is corrected without changing how it looks
(§0-F4).
Brindle — the X-linked gene
Owner-caught: the custom horse spawn egg let you build a stallion carrying
two real Brn copies, which cannot exist (a stallion has one
X). CustomHorseSpawnScreen.enforceSexLinkage now
snaps a sex-linked row's second slot to the gene's placeholder whenever the
current sex only has one real copy at that locus, and back to a real allele
when it doesn't — called after every allele edit and after the Sex
button. Confirm: add brindle, set Stallion, and cycle both allele buttons -
it should be impossible to land on two real copies.
- Does it read as brindle, and is it white? Rebuilt onto its own field: irregular white streaks, soft-edged and broken, heaviest on barrel and quarters, strong on the neck, a few crosswise strokes on the forearm and gaskin, nothing on the head. The first tuning baked out as wood grain (warp wider than the spacing) and the second came out a tan smear rather than white; this is the third. Spawn one with the custom egg — add brindle and it defaults to the expressing genotype.
- Walk round it. The single most important check on this gene:
the two sides must not match. A streak on the right need not
exist on the left, and that is the mosaicism the whole locus is about. If the
horse looks the same from both sides,
BlaschkoStripes.sideis not doing its job. - Is there a seam down the spine? The per-side rolls are blended
over two body units either side of
z = 0. Look straight down the topline for a cut. - Is the untouched head a visible seam? The neck is streaked at 0.90 weight and the head not at all. Look at the poll.
- Does
X-Brnshow correctly? Info panel and paper dump on a brindle stallion. A plain stallion must show nothing at this locus, notX-n. - The crosses. Unit-tested to textbook ratios over 4,000 foals each, but worth one real pairing: a brindle stallion × plain mare should throw no brindle colts at all and every filly a carrier.
- Frequency in a herd. 2% of wild stallions, 0.04% of wild mares. Does meeting the occasional brindle stallion feel right, or too often?
Eye colour
Owner-caught inspecting this: the dark pupil should sit toward the nose and
the white sclera toward the ears on both eyes, but the east
eye had it backwards. Cause: CoatRegions.EYE_RECTS_ADULT's east
rect was two texels short of the true pixels, so it grabbed 2 background
texels plus the pupil and missed the sclera — which broke the
deliberate west/east mirroring the raw template relies on to compensate for
the box-UV unwrap's own left/right reversal. Fixed (moved the rect from
{28,42} to {30,42}, which also feeds
tintIris); coat-golden.txt regenerated. Look at
both eyes on a horse and confirm the pupil sits nose-side on both.
The owner-reported “the coat overwrites the sclera” on foals was
this defect on the other skin, and neither an ordering nor a projection
problem: the composer already redraws the eyes after both paint phases, and
the coordinates were on the eyes. EYE_RECTS_BABY was simply
2 texels wide where the eye is 4 — the pupil and only
the pupil — on the strength of a comment asserting the foal template
has no bright sclera. It has two columns of one beside each pupil, so every
white painter and every magical gene painted over the whites of a foal's eyes
and the redraw put back the black. Now {4,20,4,2} and
{40,20,4,2}, verified against HEAD's own face
extents rather than derived. Every one of the 528 foal rows
in coat-golden.txt moved and not one adult row did.
Look at: a foal beside its dam — the whites of its eyes should now read the same way hers do, pupil nose-side on both sides. Then a foal wearing something that paints the whole head (a dominant white, a broad magic zebra), which is where the old bug was most obvious. And a blue-eyed or heterochromatic foal, since the eye-colour painters read the same rects.
- The sclera must stay white. Asserted in the pipeline, but confirm it does not read as a solid coloured block at 128px.
- Blue eyes on splash — and check a plain sabino still has
dark eyes, which is the line
KITdraws. - Blue beats amber on a horse that is both.
- The foal. A foal’s eye is the black block alone with no sclera beside it, so the tint covers the whole eye. Check it still reads as an eye.
All of it is asserted through the real pipeline in EyeColorTest, and
none of it has been seen on a horse. The whole subject is
Eye colour & heterochromia; what wants looking
at, in the order it is most likely to be wrong:
- Does a split iris read as heterochromia at all? This is the
load-bearing unknown. The iris is four texels, so a "wedge"
is one, two or three of them. Twelve shapes are in
EyePatch.WEDGES— four halves, four single corners, four three-corner shapes — and the single corners in particular may read as a stray pixel rather than as a sector. If they do, restrictingWEDGESto the four halves is a one-line retreat. - One blue eye. 22% of blue-eyed horses. Spawn a few
SW1/Nsplashes and confirm some come out with one blue eye and one dark one, and that the dark one looks deliberate rather than like a half-applied tint. - Champagne's iris. Amber 40%, hazel 35%, light brown 17%, olive 8% — spawn a handful and confirm the four are actually distinguishable at riding distance. If amber and light brown are the same eye in practice, the palette wants spreading. Also: a champagne horse now has its own baked texture where it used to share one, so watch for any coat-cache churn on a herd of them.
- Cream and pearl.
Cr/Crpale blue,Cr/prlblue-green,prl/prlpale. Confirm the blue-green reads as green and not as "the blue one but wrong", since it is the mod's only natural green eye besides champagne's olive. - Magic sectoral heterochromia. Custom egg, two different
colour alleles. Confirm both colours show, the two eyes have different
shapes, and that
green/greenandgold/ngenuinely change nothing — including on a horse that already has a champagne or cream eye, which they must not overwrite. Then trychaoson a few horses and see whether the rolled colours are ever muddy. - The foal again. A foal iris is the 2×2 pupil with no sclera, so a wedge is a quarter of a very small block. Check a splash foal with a sectoral eye still reads as a horse and not as a smudge.
A glowing cutie mark
A Cutmrk/Cutmrk horse that also carries any
light allele wears a full-bright emblem. Both are rare,
so this is a custom-egg check: add cutie mark and light, and look at the flank in the
dark. It should glow like the mane does.
Feral Mixed
- A lone wild horse’s info panel should read Feral Mixed, not Unknown.
- Breeding a Friesian to a Feral Mixed horse should give a Mixed foal, not a “Friesian × Feral Mixed cross”.
- The custom egg’s Breed dropdown should list it correctly.
The Unknown Gene Splice blacklist
Hard to check directly — the point is a negative. Breed a few dozen foals with an Unknown Gene Splice carrot and confirm none of them dies, none is a dwarf, and none comes out with fewer hearts than its parents. 13 of the 48 loci are excluded, derived rather than listed.
Open issues
Seen in-game, not fixed.
The big one is fixed: the horse’s
top and bottom cube faces were UV-swapped in
HorseSkinGeometry.faceMapsOf, so a painter that whitened
“from below” (splash, sabino belly, frame off the underline)
was flooding the back and the belly stayed coloured. Owner diagnosed it,
the two Face.TOP / Face.BOTTOM maps are now the
right way round, and measured splash white went from topline-heavy
to belly 100%, back ~35% — a proper
dipped-from-below coat. coat-golden.txt regenerated.
And splash’s own calibration is fixed too (2026-09-06) - both painters now measure against the topline rather than the whole-horse box, so a single-copy splash stops at the upper cannon instead of the belly. See §0-G for what to look at.
Frame’s topline is fixed (2026-09-06) and measured spine white went from ~75% to 0.00 at every seed. Its shape took a second pass the same day — the first one still drew a dipped horse, and the tests here did not catch it because none of them asserted the white was framed from below. See §0-F2. Tobiano crossing the topline is correct for tobiano.
Three new genes on the magic body size pattern — codominant, epigenetic, paint nothing, ~80% wild carrier rate each, so most wild horses now carry all four body-stat genes. The genotype code is 43 segments in-game (41 built-in + the two shipped spec genes; old saves will not parse). Full checklist at §0d.
Owner, 2026-09-02: the short genome string (info panel, paper dump, seed-jar
tooltip — all via GeneCodeDisplay.shortForm) never showed the
spec genes, including the shipped Suntouched /
Waterborn. Fixed with the data-model rewrite:
GeneCodeDisplay now derives its trailing gene list (curated
built-in order, then Genes.loaded()) and derives the
“baseline means absent” test from the gene’s own
expression table (does any combination mask?).
Confirm a horse carrying Suntouched or Waterborn shows it. See
§0.3.
SW2 is now the ordinary horse (built 2026-09-05, NOT play-tested)
90% of wild horses carry one copy of SW2 — the
founder table is written out as 90% SW2/N, 1% SW4/N, 9%
N/N, heterozygotes only. Measured over 20 000 draws: horses showing
any white-pattern locus went 33.3% → 93.6%, mean white coverage
of a wild horse 32.5% → 49.5%, and a foal of two wild-caught
parents is splash-bold 0.07% → 20.5%. See
the gene page.
What to look at. Spawn into a fresh world and ride past a herd: nine horses in ten should have clean-edged leg white and a face marking, and they should still look like a population rather than like one horse repeated — every copy carries its own epigenetic waterline height and its own face marking, so the question is whether that reads as variety at a glance. Then breed two wild-caught horses a few times: about one foal in five should come out visibly bolder than either parent, which is the moment this change exists for.
The white audit found that WhitePattern.splash measures its waterline
against the whole-horse height (hoof to ear tip) while the barrel
top is at 0.622 of that and the legs only reach 0.326. So S_SPLASH of
0.34 puts the line at 0.325–0.386 — all four legs entirely
white — and that is now what 90% of wild horses look like.
“Minimal marking” currently means four white legs. If the herd reads as
uniformly white-legged rather than as horses with socks, that is this bug and not
the frequency; the fix is known gap #30.
All four white loci now draw their face marking from one shared vocabulary,
WhitePattern.faceMarking(…) — three components (a patch on
the forehead, a band down the nose, a patch at the nostrils) plus a width, from which
every named marking falls out. Star and snip are new: both are
detached patches, which the old centreline band structurally could not draw. See
the pipeline page.
What to look at. Spawn-egg a horse with kit=W20/N
several times and re-roll the epigenetics: about a third should carry a plain
star and about a third nothing at all, with the odd
snip and star-and-snip. Then walk up the ladder —
kit=W20/W20, kit=SB1/N, mitf=SW1/SW1,
ednrb=O/N, kit=SB1/SB1 — and check that it reads as
star → star and stripe → blaze → bald face. Specifically worth
confirming, because none of it has been seen on a model:
- a star really reads as a star at 128px — it is only three to five texels across, and the concern is that it reads as a smudge or is lost in the template’s own shading;
- a snip lands on the nostrils rather than on the lip or the chin;
- the star sits above the eyes and not on top of the skull — the head box is pitched 30° and its bounds are the rest-pose AABB, so the projection there is approximate;
- a blaze no longer wraps under the jaw (it used to, on every locus), and a bald face still does;
- the foal, which has no separate muzzle box — the whole face is one part, so face space is measured over the head alone and a snip has to still land at the nose end of it;
- the
KIT-vs-splash margin difference is visible on the face as well as the body: aKITstar should have torn edges and a splash blaze clean ones.
Old saves. No format change — but every horse carrying a
KIT, MITF, PAX3 or EDNRB variant
repaints, because the face draws replaced the old ones in those genes’ draw
order. 330 of the 450 golden rows are byte-identical; the 120 that moved are exactly
those four loci.
The old “splash leg edges are a perfect ring” issue is gone
with the gene: whitenLowerLeg’s hard
y <= cutoff is no longer on any white-pattern path.
WhitePattern.sabino jitters each leg’s margin per texel, and
WhitePattern.splash is one wobbled waterline that crosses the legs at
an irregular height by construction. CoatRegions.whitenLowerLeg and
whitenBlaze now have no callers.
§0 — the white-pattern loci (owner-verified 2026-09-04)
The white-marking rewrite — KIT, MITF, PAX3 and EDNRB replacing the old white / splash / sabino / frame genes — is confirmed rendering correctly in-game. The eleven-item checklist that was here has moved to the session log, which is the permanent record.
EDNRB's shape was rebuilt on 2026-09-06 and every
constant in it moved — see §0-F2. What was
confirmed here on 2026-09-04 was the old frame. The three loci beside it
are untouched and the confirmation stands for them; so does everything below
about the lethal-white ratio, which is genetics rather than shape.
These four loci also grew eye behaviour that has never been looked at: complete and sectoral heterochromia, which is new since that confirmation. Eye colour & heterochromia, and the checklist in the eye section above.
Old saves will not parse their white-pattern loci. Dev only; start a
fresh world. Summon tokens: kit=SB1/N, mitf=SW1/N,
pax3=SW2/N, ednrb=O/N.
The lethal-white breeding ratio. Two ednrb=O/N
carriers should throw an all-white O/O foal about
one time in four. That is a statistic over a run of foals rather
than something a play session shows you, so it stays here: breed a carrier pair
repeatedly and check the rate looks Mendelian. The coat is confirmed
— an O/O horse renders pure white and masks everything.
The foal no longer lives. As of 2026-09-04 the health system
exists, so an O/O foal is born, named, filed in the pedigree, and
then dies. Check that too while you are breeding the carrier pair — and
see §0b below, which is where the whole health layer waits.
§0-F — the leopard complex (new 2026-09-06, NOT play-tested)
Three new loci — LP,
PATN1, PATN2 — the appaloosa spotting family, and
the model’s first cross-locus-reading gene.
:common:test 405 green,
:neoforge-26.1.2:build green, runServer boots clean
(48 segments). Old saves will not parse (48 vs 45 code segments).
The custom spawn egg — the fastest way in
- The egg’s gene list now has “Leopard complex (appaloosa)”, “PATN1 (leopard pattern)” and “PATN2 (blanket pattern)” rows. The Breed button is now a dropdown (was a cycle button) — check it scrolls all 49 breeds + “Feral Mixed”, that a pick rolls that breed into the editor, and that clicking off it dismisses it.
- Add Leopard complex →
LP/lp; add PATN1 →PATN1/n→ leopard (white body, round dark spots). LP/LP+ PATN1 → fewspot (near-solid white).LP/lp+ PATN2 → spotted blanket (white over the hips only, legs coloured);LP/LP+ PATN2 → snowcap (same blanket, no spots).- Bare
LP/lp(no PATN) → mottled — light roaning + a few white flecks;LP/LP→ varnish roan, heavier and reaching the head.
What to look at
- Spots. Do the leopard spots read as round spots at 128 px on a 3D horse, or as noise? Spacing / size are first-guess.
- The blanket. Does it actually sit on the hindquarters at the
right height, or does it read as a mid-body band? The X-cut is whole-
BODY-span and un-tuned. - Striped hooves + white sclera — drawn in the overlay
phase for every
LPhorse. Are the hoof stripes visible? Does the eye rim read as white sclera without eating the pupil? Both are first-guess constants. - Foals. The baby mesh has no muzzle and approximate geometry — check a leopard foal.
- Multi-pattern. A horse that is leopard and sabino: “white finds white” is not applied to leopard, so the sabino white just adds on top. Does that muddy the spots?
- CSNB. An
LP/LPhorse’s info panel / paper dump should list “Congenital stationary night blindness” — informational, no heart loss. - Breeds. Spawn a Knabstrupper (or Appaloosa) herd — most should show a pattern. A Mustang / Shetland should show one only occasionally. A non-appaloosa breed should never leak a PATN modifier onto a leopard-free horse.
- Cache. A
PATN1/PATN1horse with noLPmust render identically to a plain horse (it shares the texture). A fewspot and a snowcap of the same base colour must look different (they key apart).
Not built: mottled skin (the coat has no skin layer). Deferred with a note on the gene page.
§0-F2 — frame overo, rebuilt again (2026-09-06, NOT looked at)
It drew a horse dipped in white to a frayed waterline, with the
colour reduced to scraps — and it passed every test on this page, because
the tests asserted a dark spine and a white belly and a dipped horse has both.
The missing assertion was the one that says frame white is framed:
colour above it and below it. It exists now
(frameWhiteIsFramedAboveAndBelow).
Three things were wrong — an uncalibrated threshold, a band open downward, and a jag finer than one texel — and they are laid out on the EDNRB page. The lesson worth carrying: offline measurements agreed with the old code at every step. Nothing below is a substitute for looking at the horse.
Asserted in WhitePatternGenesTest rather than left as a number in
prose: spine white 0.00 at every seed, the legs under 10% and the
upper crest under 15%, the middle of the side decisively whiter than both the
belly below it and the barrel above it, the patches measurably wider than they are
tall, and the range reaching both cryptic and textbook. Swept over 400 epigenetic
seeds besides: no seed put white on the spine or the crest, and no seed came out
with a belly whiter than its own flank.
Spawn a handful of ednrb=O/N horses from the custom egg and look for:
- Does the back stay dark? The one thing frame never does is cross the topline. Walk behind a frame horse and look along the spine from the withers to the croup: it should be solid colour on every horse, with the white stopping somewhere on the flank.
- Are they splotches, in the middle of the side? This is the change, and the thing that was wrong. A frame horse should read as two or three big irregular white patches sitting in the centre of the barrel and flank, with coloured coat above them and below them. Compare side-on against a tobiano: frame is patches framed by colour, tobiano is something poured over the back.
- Does it look dipped? The specific failure to watch for, because it is what shipped twice. If the white starts at the belly and rises to a ragged line, or if the coloured coat is broken into scraps rather than being the ground the patches sit on, it is still wrong. The belly should be mostly dark, with white reaching down onto it only under the boldest patches.
- The neck. New, and it had none before: white along the lower and middle neck, sometimes joining the face white to the body white, with the crest dark. Check the crest specifically — a white crest would mean the neck band's ceiling is too high.
- Dark legs, with the odd coronet. Roughly one leg in six gets a small white band at the hoof. Confirm it reads as a coronet and not as a stray pixel, and that no frame horse comes out with tall stockings from this gene alone.
- Asymmetry. Walk around the horse. One flank should sometimes be visibly whiter than the other — if both sides always match, the side lean is too weak to see.
- The cryptic end. A clear minority of frame horses should be marked so lightly you would not call them frame — a bold face, a blue eye, and almost nothing on the body. Confirm that reads as a lightly marked horse and not as a broken one. This is deliberate; it is why frame is DNA-tested.
- The bold end. And confirm the other tail still looks like a paint horse. Total white on a bold frame is around a quarter of the barrel and neck, which is low for a paint and correct: four dark legs, a dark back, a dark mane and tail are most of the surface, and leaving them coloured is the pattern.
- Stacked. Frame has its locus to itself, so try it with splash and with sabino. A frame-plus-splash horse should be louder than either alone (white finds white) without becoming a white blob.
§0-D — dun rebuilt, and grullo made blue (2026-09-06, NOT looked at)
The whole locus was re-derived from a field guide. The dilution is a new
red-first, then black move (PigmentField.diluteNeutral)
so grullo lands on the LUT’s neutral column instead of unmasking a black
horse’s hidden red on the way out; the points now skip the
dilution outright; and the leg bars are a new field entirely.
There is also a shoulder bar and a face mask /
cobwebbing, rolled per horse. Full account:
the dun page.
The default LUT was also edited (owner) to cool its low-red column toward blue-grey, which is what makes grullo a blue rather than a neutral grey. Every desaturated colour in the mod moved a little with it — worth a glance at grey and the roans while you are in there.
Spawn dun=D/d2 on all three bases plus dun=d1/d2, and a few
of each so the per-horse rolls show:
- Grullo is a blue-grey. The headline. A
dun=D/d2black should be a slate mouse colour with black mane, tail and lower legs — not a milk-chocolate brown, which is what the old dilution produced, and not a flat neutral grey either. - Leg bars render at all. They did not, before. Look at the leg above the dark lower leg: short, uneven, soft-edged horizontal strokes around and just above the knee and hock, most of them breaking part-way round the limb. If they read as evenly spaced bracelets low on the cannon, the old field is somehow still in play.
- The four legs disagree. Three bars on one foreleg and a smudge on the other is the intended look; a matching set on all four is a bug. About one leg in five should carry none.
- Bay dun keeps black points. Tan body, black mane, tail and legs,
and no grey cuff where the black leg meets the tan body — that cuff
is the specific thing
alreadyAPointexists to prevent. - Black points are dark, not dead. Owner-reported and fixed: a bay's
points had gone flat
#000000with no strand shading, because the LUT edit moved the chart's low-red corner off exactly zero and switched off the composer's black-softening (see the pipeline page). A bay's mane should now carry the same visible hair detail a plain black horse's does — check the two side by side. This is every dark horse in the mod, not just dun: plain bay, seal brown, and anything else whose points sit on thered = 0column. - Red dun is a chestnut, near enough. Also owner-reported: the
dilution was making it a distinctly paler, more golden horse. Dun takes black
off and barely touches red, and a chestnut has no black — so a red dun beside a
plain chestnut should differ by a couple of subtle markings and almost nothing else.
If it reads as a different colour,
KEEP_REDis still too low. - The dorsal stripe reaches the tail. It only reads from above or from a low angle; walk the camera over the back. It must run withers to dock and carry into the tail hair, and it must not run down the face any more.
- The shoulder bar. On roughly half the duns: one soft diagonal smudge across the front of the barrel, leaning back as it drops. It should read as a shadow, not as a painted stripe, and never as a second dorsal stripe.
- The face. On roughly two duns in five: a darker forehead, either a broad mask or a few faint rings around it. At two texels to the body unit this is subtle — the check is that it does not read as dirt or as a white marking.
- Red dun. A pale clay-gold body with red-brown — not black — points and markings.
d1on a black horse is invisible. That is correct and deliberate. On a chestnut or a bay it should be a spine line and nothing else.- The foal. The foal mesh has no mane or muzzle, so its points are the tail, ears and lower legs only. Confirm a dun foal still reads as a dun.
§0-F4 — tobiano recalibrated (2026-09-06, NOT looked at)
Unlike frame, tobiano was not visibly broken and was not
redesigned. Its cover knob was lying — a range that read as a
1.4× swing delivered a 2.8× one — and its topline bias was
measured against the whole-horse box, so it landed on the mane instead of the
back. Both are fixed the way frame's were; the constants were then re-declared as
the range the old code actually produced and the biases re-tuned to hold the back
and legs where they were. Full account:
the tobiano page.
Over 400 seeds, before against after: markable surface 0.31–0.86 both ways, back median 0.64 both ways, legs median 0.74 against 0.76. Individual horses moved, the population did not.
Spawn a handful of tobiano=To/to horses and confirm nothing got worse:
- Does it still cross the back? The defining tobiano shape and the thing that tells it from frame. Patches should run up and over the topline, unbroken. The bias that does this now lands on the barrel rather than the mane, so if anything changed visibly it is most likely here.
- White legs, coloured head. Both unchanged in intent. The head is skipped outright by the painter, so any white on it would be a real bug.
- Are the patches still large and smooth-edged? Tobiano's edges are a hard binary cut — a half-scaled black texel reads gold, not grey — so watch for any gold fringing along a patch margin.
- The foal. Genuinely new: patch size is measured along the barrel now, so a foal should carry the same relative patch scale as an adult instead of a coarser version. Breed one and compare it beside its parent.
- The loud end. A bold tobiano is ~86% white on everything but the head. Confirm that still reads as a loud paint horse rather than as a white horse with a coloured head.
- Stacked with splash. A splash allele on a tobiano must still leave a tobiano — see §0-G, which asks the same question and is the case the saturating stacking signal exists for.
§0-F3 — the two roans, rebuilt + regreyed (2026-09-06, NOT looked at)
Classic roan and the leopard complex's varnish roan were both re-derived from a region-by-region reference, and the point of the pass was that they had drifted into being the same pattern at two strengths. They are told apart by shape, not by how much white there is. Full accounts on the roan page and the leopard page.
RoanPatternsTest is the reference's own identification checklist run
against the pipeline: classic roan even across the trunk (five zones within 0.08
luma), no shoulder shield (within 0.06), solid head / mane / tail / lower leg, a
roaned neck that thins toward the poll, and the inverted V. Varnish: dark
shields over the shoulder and hip (0.36–0.54 luma darker than the barrel),
a whitened head where classic roan's is dark, and measurably patchier.
Spawn roan=Rn/rn and leopard=LP/LP horses and look for:
- Does classic roan read as one even coat? The old gene faded front-to-back and left a nearly-unroaned shoulder, so the horse looked like it was wearing a dark cape. Walk down the side: shoulder, barrel and hip should all look the same.
- Is a blue roan slate, not grey? The density is tuned so black plus white hairs reads as a dark horse with white through it. If it looks like a grey, the white fraction is too high and the two genes are competing for the same look.
- Is there any warmth left in a blue roan or a black leopard?
Changed 2026-09-06, and the first thing to look at here. Partial whitening now
goes through
PigmentField.whiten, so the grey hairs on a black base should be neutral grey - the flecks, the fleck edges, and the whole varnish mix. Offline a side view is down from 194 warm texels to 65, which is what a plain black horse measures from the template's own hoof and nostril shading. On a screen the question is simply whether a blue roan or a black-based varnish reads black-and-white or still has a brown cast to it, especially where the white is thickest. - And is a red-based roan still red? The other half of the same
change: a strawberry roan (
extension=e/e roan=Rn/rn) and a bay roan should be exactly as warm as before - the op is a no-op on a base with no black pigment to unmask. If a chestnut roan has gone pale or grey, the correction is firing where it should not. - The inverted V. Half-way up each leg the middle of the face should still be base-coloured while the edges have roaned. This is a three-or-four-texel feature on a leg face, so the honest question is whether it reads as a point at all or just as a ragged line. If it does not, it is not worth keeping.
- The dark mask. A solid head against a roaned neck. Roughly one roan in three also gets a little forehead white — confirm that reads as a few white hairs and not as a star.
- Varnish marks. The headline change. A varnish horse should look outlined by its own skeleton: darker over the shoulder blade, the point of the hip, the elbow, stifle, knee and hock, and over the cheekbones. Check the shields do not read as patches — they are meant to be shaded regions with ragged edges, and a hard-edged dark oval over the shoulder would be worse than the gradient it replaced.
- Do the two roans look like different patterns? The whole
purpose of the pass. Put a
Rn/rnnext to anLP/LPand confirm nobody would call them the same gene. If they still read alike, the varnish mottle wants to be coarser still. - Both at once.
roan=Rn/rnplusleopard=LP/LPis in the golden set now. Confirm it does not come out white — two roaning genes stacking is the case most likely to over-shoot. - The foal. A foal has no
MANEorMUZZLEpart and its legs are short, so the chevron and the leg marks have very little room. Check a roan foal still has dark legs.
§0a — the seven magical utility genes (new 2026-09-04, NOT play-tested)
Seven new genes, a fourth coat phase, a new trait interface and two new effect verbs, none of it seen in-game. Pages: milk, magic body size, mane colour, tail colour, light, healer, verdant. Old saves will not parse — the genotype code went from 33 segments to 40 in-game. Start a fresh world.
The quickest way in is the custom spawn egg: every gene is a row, and adding one
defaults it to the first allele that does something, doubled — so
“add Light, spawn” is a one-click glowing horse. Summon tokens:
milk=Watr/Watr, body_size=Big/n,
mane_color=Mnsld/Mnstrp, tail_color=Tlsld/n,
light=Lthf/Ltmn, healer=Hlr/Hlr,
verdant=grass/grass.
80% of wild horses carry a copy, so this is no longer a rare gene you go looking for: it is the default experience of every horse. Check the population effect first and the extremes second.
- Walk into a herd of wild horses. Is the size spread visible as a spread, without any single horse looking wrong? That is the whole design of the 1.1× / 0.9× centre. If they all look identical the σ is too small; if individuals look silly it is too big.
- The walking animation. A previous build had scaled
horses sliding their feet along the ground — vanilla advances the
leg swing from ground distance and never consults
Attributes.SCALE.GeneticHorseRenderernow divides the phase by the scale. Watch a large horse and a small one walk and confirm the feet plant instead of sliding, and that an ordinary 1.0× horse is unchanged. - Spawn
body_size=Big/Bigseveral times: the percentages add, so these should be clearly larger than any wild horse. The bounded maximum is about 2.04×. Small/Small, the same. Does the hitbox match? Where does the rider sit on each?- Confirm you never catch a wild
Big/Big,Small/SmallorBig/Small— every doubled horse should be one you bred. (Unit-tested over 20 000 founders, but worth an eye in the pens.) - Breed two
Big/ncarriers: a quarter of the foals should beBig/Bigand visibly larger than either parent. This is the payoff the whole gene is arranged around. - Breed a large horse and confirm the foal inherits that percentage rather than a new roll.
- A scaled foal:
Skin.BABY’s projection is already approximate, and a foal is small twice over. - Reload the world and confirm every horse is still the size it was.
The preview applies the resolved body scale, so a
Rnd epigen. randomize visibly resizes the horse, and a size 1.14x readout sits under
the panel whenever the horse is not ordinary size. The model is capped at
2.5× so an extreme draw stays a recognisable horse; past that the
readout says (preview capped) and the number is the truth.
Check the framing still looks right at both ends.
- Each of
Lthf/Ltmn/Lteyealone: are the gold hooves / mane / eyes in the right places? The hooves in particular were only ever checked on a UV sheet. - Do they glow in the dark? The emissive layer has never drawn a gene-written texel mask — only Suntouched’s whole-part list.
- Does the horse light the ground around it? Same trailing
minecraft:lightblock Suntouched uses, so expect it to lag a gallop. - A heterozygote (
Lthf/Ltmn): both regions, in full. That is the codominance claim. - Gold eyes should keep a dark pupil — if the eye is
one flat gold rectangle,
shadeEyesis not doing its job. - On a dominant-white horse, and on a foal
(which has no mane, so a
Ltmnfoal should light the area and show nothing).
- A solid mane and a striped one: do the bands read as bands on a 3D horse, or as noise? They were tuned on a UV sheet.
Mnsld/Mnstrp: two visibly different colours on one mane. If they look like one colour, the per-copy epigenetics are not being read.- Mane and tail loci together, in different colours.
- Breed a coloured mane and confirm the foal gets the same colour.
- Healer: is the red stripe recognisably down the centre of the mane? Compare a faint one and a vivid one.
- Healer + mane colour: red on top of the colour, not under it.
- Stand within 3 blocks of a healer while hurt — do you mend, and do the heart particles show?
- Right-click a
Watr/Watrhorse with an empty bucket: water. ALava/Lavaone: lava, and check the cooldown is a minute. - A plain horse: milk from a mare only. A stallion should give nothing.
- Water and lava should work on a stallion too.
- Breed two
Watr/Lava-capable carriers — actually, breed aWatr/Watrto aLava/Lava: every foal is the clash, so the pairing should always refuse, with the chat line naming the cause. - Verdant: leave a
grass/grasshorse standing on dirt and come back. One block per beat, so it should be a patch, not a lawn. - The conversion lists are the risk: confirm a verdant horse
does not eat anything you built with. Try standing one on a cobblestone
path with
moss/moss. - Nothing should spread in the horse dimension.
A yield cancels the interaction on both sides when it fires, so
vanilla does not also read it as a mount. That was harmless while the only
yield in the game was Waterborn’s, on a rare gene. Every mare now
has one — so right-clicking any grown mare with an empty bucket
gives milk instead of mounting, always.
Worse on the cooldown: fulfil returns early when the horse is
still recharging, but the event is cancelled anyway, so for 200 ticks after
milking a mare you get neither milk nor a mount and no feedback at
all. Check how bad that feels. The fixes, in order of size: don’t cancel
when the cooldown blocks it; require sneak; or gate milking on
tamed so wild mares are unaffected (roadmap
§7 wants that rule anyway).
A milk horse and a verdant horse are indistinguishable from an ordinary one until you put a bucket under them or watch the floor. That sits awkwardly beside healer, which draws a stripe precisely so you can see what it does, and it is logged as a gap rather than fixed — a marking would want to be part of the locus rather than bolted on.
§0b — the trait, size and health system (new 2026-09-04, NOT play-tested)
Thirteen new genes and a whole new subsystem, none of it seen in-game. Machinery: the horse’s body. Old saves will not parse — the genotype code went from 20 segments to 33, and then to 40 with the magical utility genes (§0a). Start a fresh world.
The owner’s next change is to make this easier to test before working through the list below. Expect the tooling described here (the spawn egg flow especially) to move; re-read this section against the code before trusting the steps.
The custom horse spawn egg is the tool. Adding a gene in its editor defaults it to homozygous for its first non-baseline allele, which for every health locus is the affected genotype — so “add PLOD1, pick Foal, spawn” is a one-click lethal foal. Spawn Adult instead and it lives (the death handler only touches babies), which is how to look at a dwarf without it dying.
Stats are genetic now — the random roll is gone
- Ride a wild-caught horse and a bred one. Wild speed should sit between
0.17and0.31; an all-wild-type horse is exactly0.1875. Two horses with the same genotype must have identical stats — that is the whole point, so spawn two of the same code and compare the info panel. - The info panel now shows speed, health, jump and size (size as a word: dwarf / small / average / large / draught) plus any conditions. Check the panel still fits — it gained two rows and a condition list.
- Right-click with paper: speed, health, jump, size, and a
conditions:block with full descriptions. - A reload must not heal an injured horse. Hurt one, quit, rejoin — its current HP should be unchanged, not restored to max.
- Breed a foal and check the
vs parentscolouring still works (green / amber / red on speed and health).
Size — the first visible non-coat gene
- Spawn
hmga2=p/pandlcorl=L/Lside by side. The pony should be visibly smaller and the tall horse visibly larger;Attributes.SCALEscales the hitbox too, so check you can still hit and mount both. - A scaled foal is the unverified case.
Skin.BABY’s projection is already approximate; ap/pfoal at ~0.88 scale has not been looked at. Also check the rider sits correctly on a large and a small horse. - An ACAN dwarf (
acan=D2/D3) should be much smaller again — dwarfism multiplies where the height loci add, so a dwarf pony should be smaller than either alone.
The lethals
“Foals dying right after birth also works.” The first thing in §0b ever confirmed in play — the whole trait, size and health system has carried “NOT play-tested” since 2026-09-04, and the lethal path is the part of it with the least margin for being quietly wrong: a foal that should die and does not is a silent failure, and one that dies when it should not is a ruined line.
What this does not yet cover, because it was not reported either
way: whether the death message resolves rather than printing the raw key
death.attack.horsegenetics.genetic_defect. The four bullets below are
untouched.
- It has to out-damage the healing. Stand a dying foal next to water and a hay bale — gated healing must not save it.
- Lethal at conception. Two
met=met/Ncarriers should sometimes eat the food, show hearts, and produce no foal plus a chat line saying why. Roughly one pairing in four. - An adult must not die. Spawn an adult
plod1=ffs/ffs— it should live indefinitely. Same in the horse dimension: a pen horse that rolls lethal white must not start dying. - Check the family tree still renders with a short-lived foal in it.
The server config
run/phc/server.toml,health.mode. SetNO_DEATHS: a lethal foal should be born with very few hearts and live, and a MET pairing should produce a foal.- Set
OFF: a dwarf should be full size with full hearts, and no conditions should show anywhere. - The genotype must not change in any mode. Compare a horse’s genetic code across all three settings — identical, or the whole design is broken.
Carriers
- A carrier (
plod1=ffs/N) must be indistinguishable from a clear horse: full stats, no conditions, and the short genome string showingnffs. - Breed two carriers repeatedly and check the affected rate looks like one in four.
§0d — magic speed / health / jump (new 2026-09-05, NOT play-tested)
Three new genes on the magic body
size pattern — codominant, epigenetic, paint nothing. Pages:
magic speed,
magic health,
magic jump. The genotype code went from 41
segments to 44 in-game — old saves will not parse, start
a fresh world. Like magic body size, about 80% of wild horses carry a
copy of each, so most wild horses now carry all four. Summon tokens:
magic_speed=Swift/Swift, magic_health=Hardy/Hardy,
magic_jump=Springy/Springy (and the mirrors
Sluggish / Frail / Leaden).
- Walk into a herd. Same test as magic body size: the
speed / jump spread should read as a spread across the paddock without any
one horse feeling wrong. If every wild horse runs at the same pace the
σ is doing nothing; if a random wild horse bolts like a
double-
Swiftit is too wide. magic_speed=Swift/Swift. Ride it next to an ordinary horse — it should be about a fifth faster (mean), more when the copies rolled well. Then spawn one that is alsomstn=C/C: it must be faster still, and by the ratio — the magic multiplies the natural speed, it does not add a flat amount.magic_jump=Springy/Springy. Does it clear a noticeably higher wall?Leaden/Leaden— does it visibly struggle with a 1-block jump vanilla horses clear?magic_health=Hardy/Hardy. The health bar in the mounted GUI should show more hearts than a wild horse.Frail/Frailstacked with a survivable disorder (b4galt7) — confirm the horse still has at least half a heart and does not die on spawn (theMIN_HEALTHfloor).- Config OFF. Set
health.mode = OFFand confirm aHardy/Hardyhorse keeps its extra hearts — it is not a disorder, so the switch must not touch it. (Onlyb4galt7/acan/ the lethal foals should change.) - Confirm you never catch a wild homozygote or a wild
Swift/Sluggish— every doubled horse is one you bred. - Breed two
Swift/ncarriers: a quarter of the foals should beSwift/Swiftand faster than either parent, and a fast foal should inherit its parent’s percentage, not a fresh roll. - The info panel and paper genome dump gained no rows, but the resolved speed / health / jump they already print should reflect the multiplier.
- Reload the world and confirm every horse is still the speed / hardiness / jump it was.
§0e — breeds, herds & aggro (2026-09-05, partly play-tested)
49 breeds, biome-weighted herd spawning, cross / mixed breeding labels, and per-breed stat bands feeding the four magical body-stat genes. Full design: breeds.html. Nothing here has been seen in a play session; the server boots clean with the biome modifiers loaded.
- Horses spawn, in herds. Fly to a taiga, jungle, badlands, swamp, snowy biome, mushroom fields — none spawn horses in vanilla. You should see packs of 3–6 that read as one breed, and only the rare truly-isolated horse. Breed + herd assignment owner-confirmed 2026-09-05.
- No server crash (the load-bearing one) — NOT yet
re-confirmed. A
DistanceManager.runAllUpdatesNPE has crashed the server three times after a few minutes of fast flight through fresh chunks:HorseRecords.applyTraitsToEntitywritesAttributes.SCALE, a non-1.0 scale makesrefreshDimensionsrun a collision scan that can force-load a chunk, and doing that fromEntityJoinLevelEventor aserver.executetask re-enters the chunk ticket pass. Breeds made it reliable — a breed pins the body-size locus homozygous, so every Fjord / Percheron / Falabella gets a real scale change on its first resolve. Fix (2026-09-05): all record / coat / trait / herd work now runs fromHorseFoundingTickHandleronEntityTickEvent.Post— after the tick's chunk updates, with the horse's surroundings already loaded — and theonHorseJoinserver.executedeferral is gone. Fly a long way through unexplored terrain, near lots of herds (draft-heavy biomes especially), and confirm it holds. - A herd is one breed; solo horses are Feral Mixed and never in a
clump. The load-bearing check — this is the
fourth attempt at herd formation (the owner confirmed the third
still produced mixed-breed herds). Every member of a pack must show the
same breed. A lone wild horse must read Feral Mixed. You
must not see a group of horses standing together with two or more
different breed labels. The 3rd revision founded on the join event, when
a spawned pack's other members are not query-visible yet — so every
horse founded a herd of one and came out Feral Mixed (owner
confirmed). The 4th (2026-09-05) founds from
HorseFoundingTickHandler20 ticks after spawn, once the pack is loaded, andHerdManagerflood-fills the whole connected clump (aNaturalSpawnerpack walks each member a cumulative ±5 blocks, so four routinely span past 32 end-to-end) and elects a deterministic lowest-UUID lead whose UUID seeds the breed draw, so every member lands on the same herd whatever order the tick handler reaches them. Owner-confirmed working 2026-09-05. Still watch: the last horse of a very spread pack must join the herd, not fall out as a lone Feral Mixed. - Traditional vs bachelor bands. A traditional herd is one stallion + mares (+ the odd foal at vanilla's ~5% rate); a bachelor band is all stallions, no foals. Roughly 70/30.
- Herds move as a unit. A spawned pack should stay clumped and wander together following one horse (the lead stallion, or a random bachelor). They should not scatter to the horizon.
- Wild horses aggro like wolves. Hit one wild horse: it and its whole herd should turn and kick you (4 damage). Run out of sight for ~3 s and they go back to neutral. Tamed horses never do this.
- Dev conveniences. F8 is a toggle now — press once and nearby horses stay glowing until you press it again (chat says ON / OFF). A stick tames / a clock ages a foal anywhere in a dev build now (not just the horse dimension).
- The info panel shows a breed. Mount a wild horse, open the panel (E): a breed name sits under the “mare / stallion gen N” line. A biome with assigned breeds should mostly show a real breed; the odd one reads Feral Mixed.
- Paper dump. Right-click a horse with paper: it now
prints a
breed:line and aherd:line (band type, "this horse is the lead" or "led by <name>", member count); generation and the ancestors list are gone. The dev[coat]chat line still gains a[Breed Name]tag. - Custom spawn egg “Breed:” preset. The egg
editor has a
Breed:cycle button (right column, under Sex). Cycling to a breed should load a fresh wild individual of it - genes, epigenetics and sex all change - and the spawned horse’s panel should show that breed. PickFeral Mixed(the first entry) and it spawns an unbred horse with whatever genome is in the editor. - Breed reads on the body — big horses are bigger now. A Percheron / Shire / Clydesdale should visibly tower over the player (scale ~1.2–1.4); a Quarter Horse should look ordinary (~0.96); the gap between them should be obvious. Falabella / Shetland still tiny. Thoroughbred / Standardbred herd visibly faster than a draft herd.
- Colour matches the breed. Friesian = jet black, no white. Suffolk Punch / Haflinger = chestnut. Fjord / Przewalski = dun with a dorsal stripe. Gypsy Vanner / Paint = tobiano pinto. Appaloosa / Knabstrupper currently show only faint roan (leopard complex not built).
- Breeding labels. Same breed × same breed → that breed. Two breeds → “A × B cross” (alphabetical, order-free). Cross × a parent breed → same cross. Cross × an outsider → “Mixed”. Check the foal’s panel.
- Cross stats. A Thoroughbred × Arabian foal should still be fast; a Thoroughbred × Friesian foal should regress toward ordinary speed (Friesian pins no speed band).
- Seed jar. A stallion seed jar carries the donor’s breed; a seed-jar foal from a pure mare + a pure (different) sire should read as their cross, not “… × Feral Mixed cross” — and a seed-jar foal from a feral donor should read plain Mixed.
- Old worlds. The genotype code changed (44 → 41 segments — the Test gene was removed this session, and there is no Test card in the wiki or gene picker any more). Pre-session saved horses will not parse their old code; start a fresh world.
§0c — the particle locus (new 2026-09-04, NOT play-tested)
Forty alleles on one gene, a new ability interface, and a rebuilt
emitter verb — none of it seen in-game. Page:
particle. Old saves will not parse: the genotype
code went from 40 segments to 41 in-game. Start a fresh world.
The way in is the custom spawn egg. Adding the gene defaults it to the first allele
that does something doubled, which is Dst/Dst — coloured dust.
Summon tokens look like particle=Rflm/n. You have to make the
horse walk: the trail fires only while it is moving on the ground, so a
horse standing in a spawn pen shows nothing and that is correct.
| Check | Where | What right looks like |
|---|---|---|
| A trail appears at all | Spawn particle=Dst/n, ride it | Coloured dust behind the horse while moving, nothing while stopped |
| The six body sites read as different places | Spawn the same allele several times over, re-rolling with Rnd epigen. between | head / spine / all four hooves / front pair / back pair / tail are visibly distinct origins. The hoof sites are the ones most likely to be wrong — they are computed from the bounding box and yaw, so check they track when the horse turns |
| Two horses of one allele differ | Rnd epigen. on Rflm/n repeatedly | Different colours, sites and densities every time; the particle itself never changes |
| A codominant pair shows both, independently | particle=Rflm/Csmk | Flames and campfire smoke, from two different places, in two colours — not one merged stream |
| A non-codominant pair hides one | particle=Dst/Soul | Dust only. Indistinguishable from Dst/n — that is the point |
| A foal inherits the exact look | Breed a trailing stallion onto a plain mare | Roughly half the foals trail, and those that do match the sire exactly — same colour, same site, same count |
| All forty particles render sensibly at horse scale | Walk the list with the spawn egg | The suspects are the emitter-style ones, which in Bedrock spawned other particles and here are plain: Snc (sonic ring), Shrk, Raid, Skl. Also Sklk2 (a vibration aimed at the horse itself) and Dig (a sculk block particle) — both were substitutions, not the named particle |
| The colour-carrying particles are not invisible | particle=Bwswrl/n, Whtswrl/n, Bkswrl/n, Dst2/n | They are visible and coloured. ColorParticleOption reads the alpha byte, so a bug here shows as nothing at all rather than as a wrong colour |
Dst2 actually fades | particle=Dst2/n | Two colours, one becoming the other — not a single flat colour |
| Density is not overwhelming | A count-4 horse at a gallop, then a herd of them | 20% of moving ticks × up to 4 particles × up to 2 emitters. If a single horse is too much, EMIT_CHANCE is the one number to turn down |
| The wild rate feels right | Walk the overworld, or the horse dimension corridor | Roughly 1 wild horse in 13 trails something. If it reads as noise rather than as a find, WILD_ALLELE_FREQUENCY is the dial |
| Sites track a scaled horse | Pair it with body_size=Big/Big | The trail comes off the big horse’s own hooves, not off where an ordinary horse’s would be |
| A foal emits | Any trailing foal | It emits. The sites are computed from the bounding box, so they should scale down — but nothing has looked |
Ten of the forty alleles are named after Bedrock particles with no Java
equivalent and carry a substitute — the table is on
the gene page. Two more
(Bigflm, Cndlflm) were cut rather than substituted,
because Java flames carry neither a colour nor a scale and the pair would have
been indistinguishable from alleles that already exist.
§0f — shearing, milking rules, carrots, the gene database (new 2026-09-05, NOT play-tested)
A big multi-system pass — milking rules, shearing, the carrot family, the
gene database and gene metadata. Nothing
here has been seen in-game. Reference: the carrot
family, gene effects (the yield
else-branch + the full_health flag),
the gene format (format 3).
Determinism — the thing to check first
- An un-fed pairing must breed exactly as it did before.
GameteBias.NONEon both sides is asserted bit-for-bit identical to the oldbreedWithandcoat-golden.txtis untouched, but confirm a foal from two carrot-free parents comes out the way it used to (same coat, same stats, same odds).
Shearing (§12)
- Right-click an adult horse with shears → 1–3
horse_hairdrop, a shear sound, hair particles. Shears take durability. A foal says “no coat to shear yet”. - Shearing the same horse again the same Minecraft day says “hasn’t
grown back”; after a full day (24 000 ticks) it works again. The
gate is a stored game time on
HorseCooldownsAttachment, so it survives a relog. - A tamed horse gains +5 bond per shear (honours the daily cap); an untamed horse can still be sheared for hair.
- No sheared look yet — the horse looks unchanged. Deferred (gap #33).
- Craft chain: 4 hair → bundle; 3 bundle → braided rope; 4 bundle
→ hair cloth; all reverse.
braided_rope/hair_clothborrow the bundle texture — need art.
Milking rules (§7)
- A tamed mare at her own full health, right-clicked with a bucket, gives milk — once per Minecraft day now, not every few seconds. On cooldown she says “nothing to give yet” rather than silently eating the click.
- An untamed mare: milking does nothing and you mount her
normally (the yield’s
whenfails, nothing is cancelled). - A tamed mare below her own max health: currently gives neither milk nor a mount and no message — a known gap (gap #25). Heal her and it works.
- Milking a stallion → a kick (half a heart) + “the stallion kicks you”. Milking a foal → “a foal has no milk to give”.
- Water / lava milk (
milk=Watr/Watr/Lava/Lava) still work off any grown horse, on their own shorter cooldowns.
Breeding carrots (§14)
- Feed a carrot to a breedable adult → a coloured particle burst (purple epigenetic-splice / orange gene-splice / blue stabilizer / green magnifier / gold known-gene-splice) + the horse enters breeding mode like a golden carrot. A foal says “cannot be bred”.
- Unknown Epigenetic Splice: breed a fed parent → the foal’s alleles are unchanged from an un-fed pairing (same seed), but its epigenetics differ — check via the paper dump or a re-rolled bay’s leg heights.
- Stabilizer / Magnifier: feed one parent
that is heterozygous at a visible locus (say
E/e), breed against ane/epartner — stabilizer → the foal always gets the dominant copy; magnifier → always the recessive. On an all-homozygous horse the carrot says “does nothing for it”. - Unknown Gene Splice: feed one parent, breed several times — a different single locus should be re-rolled each time (off the foal RNG); never the sex locus.
- Known Gene Splice carrot: craft one — golden carrot +
research paper + horse hair (or hair cloth) + the gene’s rarity item
(iron/gold/diamond/emerald/netherite ingot/nether star) + one flavour
item. The output names the gene in its tooltip. Feed it and breed →
that parent is treated as
n<Gene>for that gamete (25/50/25 when both parents carry the carrot). - Combine: two or more carrots in the grid → one carrot carrying all the effects. Stabilizer + magnifier, or two Known Gene Splice carrots for the same gene that disagree, → the recipe simply does not resolve.
- The window lapses (~30 s, like love) if the pair doesn’t breed; it is consumed when they do.
Gene database & papers (§16)
- The Horse Browser’s Gene Database tab now works outside creative: an undiscovered gene is a dim name + a nudge; a discovered one shows full detail, the variants seen, and “Gene carrot recipe: locked/unlocked”. Creative shows everything.
- Tame a horse carrying a non-baseline allele, or breed a foal with one → those genes appear in the database. Confirm the sync fires (relog should keep them).
- A research paper (from a loot chest, or written) — right-click → “added X to your gene database” + the carrot line unlocks; the paper is consumed.
- Write research paper button in the detail pane (discovered genes with a carrot): with a book in your inventory → one book spent, a paper for that gene handed back.
- Loot injection: open dungeon / mineshaft / stronghold /
village / mansion / outpost chests — a research paper turns up
~18 % of the time, gene weighted by rarity. If the boot log says
Couldn’t parse … loot_modifier, the chest ids drifted — the modifier file is atdata/horsegenetics/loot_modifiers/(plural, no index).
Wanted (not built yet)
The eyes render correctly everywhere, but they are copied verbatim from the
template (CoatRegions.redrawEyes). Wants a gene — and the
classic hook is blue eyes on cream double-dilutes, which would
make it the first gene to read MATP’s
expression for something other than pigment.
Still to verify
The LUT gene (was §0-A) is owner-confirmed working in game — moved to the session log.
0-B. Horse Browser is now a container menu + a Crafting tab (built 2026-09-05, redesigned + two gene buttons added, NOT play-tested)
The Horse Browser was rebuilt from a client-only Screen into a
server-synced AbstractContainerScreen over a new
HorseBrowserMenu (menu/ package, new
MenuType). Pressing H now sends
OpenHorseBrowserPayload and the server opens the menu.
The first layout was cramped and overlapping; it was redrawn.
The Gene Database tab is now a full-window reference again
(list left, scrolling detail right, no slots — every menu slot
goes inactive on this tab). The Crafting tab is a compact centered
panel (a 3×3 grid + result + the player inventory) with the
gene list still down the left. A tab strip sits at the top-centre of the
window on both. All custom drawing is in screen coords (the container's
leftPos/topPos translate is undone in extractLabels).
- Press H → the browser opens (server round-trip). Esc closes.
- Layout sanity (the point of the redraw): nothing overlapping. The filter box, the “N genes” count and the first list row are clear of each other; the detail heading / tags / summary / alleles / phenotypes stack without collision and scroll as one; the “Write research paper” button sits below the detail text, not under it; on the Crafting tab the grid, the result slot, the “Gene paper” note and the inventory do not touch. Check at GUI scale 2, 3 and 4.
- Gene Database tab: list, filter (name / key / allele), selection-follows-filter, both scrollbars, the discovered vs undiscovered styling. No slots, no slot-highlight, no item tooltips anywhere on this tab.
- Two gene buttons appear when a discovered carrot gene is
selected (bottom of the detail pane on Gene database, right of the grid on
Crafting):
- Craft research paper — consumes one book
from the inventory and gives a
research_paperfor that gene (the old “Write research paper” flow; still needs the gene discovered, i.e. in the DB, even in creative). No book → a chat message, no consume. - View splice recipe — switches to the Crafting tab and fills the 3×3 grid with that gene’s Known Gene Splice ingredients: real items pulled from your inventory where you have them (golden carrot, this gene’s paper, horse hair, the rarity ingot, sugar as a flavour), ghost placeholders where you don’t. It empties the grid back to your inventory first. It does not craft — but with all five real, the result slot shows the carrot to take normally. Verify the ghosts render dimmed in the empty slots and disappear as you supply the real item.
- Craft research paper — consumes one book
from the inventory and gives a
- Crafting tab: the left list shows only discovered, carrot-bearing genes (creative: all with a carrot). The 3×3 grid + result slot + full inventory render and take items.
- Book → gene paper: a single book in the grid + a
discovered gene selected → the result is that gene's
research_paper. Take it → one book consumed. Undiscovered gene (survival), or anything besides exactly one book → no result. - Known Gene Splice carrot: golden carrot + the gene paper
+ a hair item + the rarity ingot + ≥1 flavour → the carrot
(
KnownGeneSpliceRecipe). Combining carrots: 2+ breeding carrots → one merged carrot; contradictory pairs give nothing. - No vanilla recipes: planks→sticks etc. in the grid produce nothing.
- Shift-click / drag / number keys behave; closing returns grid items to the player. Switching tabs while holding a picked-up stack is blocked.
0-C. Splash white now always wears a bold face marking (built 2026-09-05, NOT play-tested)
Regression fix. After the 2026-09-05 face-marking-family rework,
MITF / PAX3 splash at single-copy strength
(~0.35) mostly landed on a small star, a snip, or nothing — splash
horses were coming out bare-faced. WhitePattern.splash now runs
its face marking at a boosted strength
(SPLASH_FACE_BOOST = 0.34): a single-copy splash reads as a
blaze, and a homozygote or a two-locus splash as a
bald face — the splash phenotype (dipped from below
and a bold blaze). Same RNG draw count, so alignment is preserved;
coat-golden.txt regenerated (splash rows moved). New
WhitePatternGenesTest.everySplashHorseWearsAFaceMarking.
- Spawn a single-copy splash (
mitf=SW1/Norpax3=SW2/N) over a few seeds — every one should have a clear blaze (not a star, not nothing). - Homozygous / two-locus splash
(
mitf=SW1/SW1, ormitf=SW1/N pax3=SW2/N) → a bald face taking the eyes and the sides of the head. - Confirm the blaze is crisp-edged (splash jag 0.11), not
torn like a
KITsabino face. - The KIT and EDNRB face markings are unchanged — only splash was boosted.
0-D. The cutie-mark gene (built 2026-09-05, NOT play-tested)
A magical, recessive gene (horsegenetics.cutie_mark, priority
196, Cutmrk / n).
Cutmrk/Cutmrk wears an emblem of 1–3 flat items on both
flanks, drawn by a client render layer (CutieMarkLayer) on top
of the coat and every white pattern. Paints nothing in the bake (all
outcomes wild types, like particle), so the genotype code gains a segment
(43 built-in genes, 45 in-game) but the catalogue is
unchanged; old saves won't parse. :common:test 391 green. See
gene-cutie-mark.html.
- Spawn a
cutie_mark=Cutmrk/Cutmrkhorse (custom spawn egg → add the gene; it defaults to the homozygote): an emblem of item icons should appear on both flanks, and it should still show over a dominant-white or heavily-splashed horse. - Placement / scale — reworked twice on 2026-09-05.
Now anchored mid-haunch (body-local
z ≈ 0), high on the flank (y ≈ -4). Check it sits on the hindquarter — not mid-barrel, not floating off it or buried in it, and nothing spilling past the rump or the belly line — at rest and while walking, adult and foal, and at differentSCALE(a magic-size horse). Report where it actually lands. - Multi-icon layout (2–3 items) — icons now
shrink with the count, sit closer together
(
SPACING0.16 → 0.085), each steps a little toward the viewer (DEPTH_STEP) and is fanned 5°, so it should read as a clean stack of stickers with an obvious top one — not the old co-planar z-fighting / clipping. Re-roll epigenetics to see 1→3 and row vs triangle. - Orientation — the icons were rendering
upside down; a
+PIin-plane spin was added (2026-09-05) to counter entity-model space being drawn rotated 180° about Z. Confirm the item icons now read upright (and not mirrored/back-to-front) on both flanks. If the stack order looks reversed (top icon at the back), theDEPTH_STEPsign needs flipping. - Row vs triangle: re-roll epigenetics (spawn egg button) to cycle count 1→3 and the row/triangle layout.
- The item pool: block items should never appear (they'd be little 3D cubes); modded flat items should be in the mix. A couple of odd flat items (spyglass, trident, fishing rod) may read poorly — note any that look broken.
- Determinism / inheritance: two
Cutmrk/Cutmrkhorses of the same epigenetic seed wear the identical mark; a foal that inherits theCutmrkcopy inherits its parent's mark exactly. - Carrier (
Cutmrk/n) shows nothing; breeding two carriers throws a marked foal ~1 in 4. - Perf: a paddock of marked horses shouldn't stutter (the layer resolves up to 6 item models per marked horse per frame).
0-E. Name-tag rename window (built 2026-09-05, NOT play-tested)
Right-clicking a horse with any name tag (plain, enchanted,
or anvil-renamed) opens HorseRenameScreen instead of doing the
vanilla thing.
- Plain name tag off the creative menu on a tamed horse → the window opens, both fields prefilled with the current registered name. Anvil-renamed tag → same window (the tag's text is ignored now).
- Confirm with an edited name → the horse's shown name changes, and one name tag leaves the stack (nothing consumed in creative). The paper dump (right-click with paper) and the info panel show the new first / last name.
- Cancel (or Esc) → no tag consumed, name unchanged.
- Both fields blank → the Rename button does nothing.
- Walk away from the horse before confirming → the server rejects it (out of range), nothing consumed.
- Vanilla did not also set the entity's custom name (the floating-nametag string) — the interaction is cancelled both sides.
- A wild horse with no record yet: right-click does nothing (it waits for the join handler to assign the initial name).
0. The Horse Browser (H) & the per-horse gene popup (new 2026-09-05)
First slice of the “H page”
(HorseBrowserScreen) plus a per-horse gene inspector
(GeneInspectScreen). Nothing here talks to the server —
it is all common/ data already on the client. Built, not
play-tested.
GeneInspectScreen and the grey inventory panel are
deleted; the per-horse half of this checklist is now
§0-AG, and the browser gained a third tab
there too. The browser checks below still stand as written. The per-horse
ones are kept because what they say about which loci are worth
listing is still what HorseInfoScreen does.
- Press H in-game (rebindable, category
“Miscellaneous”, lang key
key.horsegenetics.horse_browser) → the browser opens when no other screen is up. Esc closes it. Confirm it does not fight the vanilla H-less defaults or any other mod’s bind. - Gene Database tab, in creative: every registered gene listed alphabetically by display name; the count line sits clear of the filter box; the list scrolls with the wheel and its scrollbar tracks.
- Filter box: typing part of a gene name (“splash”), a key (“kit”) or an allele token / label (“SW1”, “cream”) narrows the list; clearing it restores all. Selection follows the filter (keeps the current gene if it survives, else jumps to the first hit).
- Detail pane: gene name, then
key · natural/magical · priority N · [no coat effect], then the one-paragraphGene.description()summary (new; fromGeneDescriptions— every built-in has one, a data-driven gene shows “no summary…”), then every allele (token — label), then every phenotype with itsExpressionsentence and inlinewild type/masks other genes/varies per horseflags. Pane scrolls independently. - Outside creative: the tab is a two-line note, no list.
- Tab strip: one tab for now; clicking it is wired
(
tabAt) so a second tab drops in without touching input code. Check the strip draws and the active tab reads as active. - Superseded 2026-09-07 — see §0-AG.
The grey panel and
GeneInspectScreenare both deleted; the i button opensHorseInfoScreeninstead, and its Genes / Coat / Other tabs cover everything the paragraph below describes. Kept for what it says about which loci are worth listing, which the new screen still follows. — Horse inventory panel (E on a tamed horse): the compact genotype line is gone from the grey panel; a new “View Genes” button sits above “View Family Tree”. It opensGeneInspectScreen— a full-window popup, the horse’s two allele tokens in column one and the genotype-context phenotype sentence (genotype.expressionOf(gene)) in column two. It lists sex, extension and agouti always, then every gene the horse carries something other than the plain baseline at — an expressing coat gene, or a heterozygous carrier (thenJ/nC/nCrthe paper dump lists). A gene at its baseline is left out. Expressing rows are green, carrier rows a muted gold, and both show the outcome’s real name and sentence (a one-copy MSTN reads “Middle distance — half a sprinter’s speed for half its hearts”, not “no effect”). Confirm the alleles shown match the coat you see. Closes to the game (like the family tree), not back to the inventory. - Check the panel layout still fits with three stacked buttons (View Genes / View Family Tree / barn-name row) — the constants are eyeballed and the condition list can be long.
0. Dun becomes a three-allele locus (new 2026-09-03)
Dun now carries D / d1 /
d2 — six combinations on three outcomes. d1
is the new one: it draws the dorsal stripe with no dilution,
so a horse can have primitive markings and not be a dun. The old catch-all
d is gone; the baseline allele is d2, so
summon with dun=D/d2, not dun=D/d.
235 :common:test pass (8 of them a new DunGeneTest),
:neoforge-26.1.2:build is green.
The dun segment’s allele tokens changed, so a save from before this will
not parse its dun locus. Start a fresh world. Every one of the
240 pre-existing golden rows is byte-identical though — only the 12 new
d1 cases were added — so nothing else about any coat moved.
- A
d1bay shows a spine line and nothing else. Summonagouti=A/a dun=d1/d1beside a plainagouti=A/a. The body must look like an ordinary bay — only a touch warmer through the barrel — with a visibly darker line down the spine. If the whole horse reads noticeably lighter,MARKED_KEEP_RED_CHESTNUTis too low; if you cannot find the stripe at all, it is too high. - A
d1chestnut is the clearest case.extension=e/e dun=d1/d2: an ordinary chestnut with a distinctly redder dorsal line running nose → tail. - A
d1black shows nothing — that is correct.dun=d1/d1on a plain black must be indistinguishable from a plain black horse (it composes byte-identically). If it comes out brown or darker than a plain black, the keepRed ramp has been broken — that is the exact failure mode the constants are shaped to avoid. Dstill does everything it did.dun=D/d2on black / bay / chestnut → grullo / bay dun / red dun, dorsal stripe and leg bars. Unchanged bytes, so this is a regression check, not a new look.D/d1is a dun, not a blend. A horse carrying one of each must look exactly likeD/d2— dominance for the dilution isD > d1, and the two land on the same expression.- Marked horses are common in the wild now.
d1is 1 in 10 per allele, so roughly 18% of wild spawns should carry a dorsal stripe with no dilution, against about 8% duns. Spawn thirty and look along their backs; if you see none, the founder table is not being drawn. - The genome display reads sensibly. The short form writes
nDforD/d2,nd1ford1/d2andd1d1ford1/d1— check the info panel, the paper dump and a pen sign agree. - Dun in the pens. The catalogue tally is off the entrance sign (the corridor is random now — item 4), so check dun in a pen the ordinary way: some pen horses should carry a stripe and no dilution.
0.1 Sex is a gene (new 2026-09-03)
Sex-linked genes, first half:
horsegenetics.sex is registered at priority
1 with alleles X / Y. HorseRecord.sex is no
longer a field — it is read off the genetic code — and
HorseRecords.randomSex is gone, so a foal’s sex is
inherited rather than rolled. 227 :common:test pass, parity is
3,832 checks across 48 cases, :neoforge-26.1.2:build is green and
runServer boots clean at 20 segments.
The genotype code gained a segment and every gene’s epigenetic
seed shifted with its position in codeOrder(), so a save from
before this change will not reproduce its horses. Start a fresh
world. (90 of the 240 golden rows are byte-identical — the
deterministic coats — which is the proof the pipeline itself did not
move.)
- Wild spawns come in both sexes. Spawn a dozen; the info panel should show a mix of Mare and Stallion, roughly half and half. A run of twelve of one kind means the founder table is not being drawn.
- A foal’s sex is inherited. Breed one pair repeatedly (or use the seed jar) and watch the foals: both colts and fillies should turn up. Two mares can never make a colt — but they cannot breed at all, so the real check is that the sex shown on the foal matches what the family tree and the paper dump say, every time.
- The same-sex breeding gate still works. Two mares or two stallions in love mode must refuse to produce a foal — that gate now reads a derived value, so it is worth re-confirming.
- A mare and a stallion of the same colour look identical. Spawn both from the custom egg with the same genome; they must render the same coat. (They now share one baked texture — if one is a plain white horse, the coat-code / texture-id work is wrong.)
- The custom spawn egg’s Mare / Stallion button still works, and sex is not in the gene list at all (it is filtered out; the button owns that locus).
- Every pen still has one mare and one stallion, and the pen signs do not print sex — the short genome form leaves it out.
- The seed jar still refuses a mare (collection) and
refuses a stallion (impregnation) — both sides now read
the sex out of the genome rather than a stored field, and the jar’s own
sexcomponent is gone. - A reloaded horse keeps its sex. Save and quit with a known
stallion, come back: he must still be a stallion. (The record no longer carries
a
"sex"NBT key, so this is really "does the genetic code survive", but it is the cheapest way to catch a regression.)
0.2 The combination-table rewrite — no more dominance (new 2026-09-03)
The combination table:
DominancePattern is deleted; every gene declares an
Expression per distinct outcome and one function mapping any allele
combination to one of them; randomPair is replaced by a per-combination
FounderTable; cream and pearl merged into three-allele
MATP; the JSON gene format moved to
"format": 2; and the epigenome moved onto
HorseRecord (the separate coat attachment is gone). 213
:common:test pass at the time (227 now), parity is 3,832 checks across
48 cases, runServer boots clean (19 segments then,
20 since the sex locus). Machinery:
Genetics model,
the gene file format,
MATP.
The genotype code lost a segment (cream + pearl → MATP) and founders now
draw one nextFloat() per gene instead of two nextInts,
so old saves will not reproduce their horses. Dev-only, no
saves to keep — but start a fresh world rather than wondering why a
familiar horse changed.
- Wild spawns still render correctly and show a wide variety. This is the whole-pipeline check: founder draws, the expression table, and the record-borne epigenome all changed under it.
- A cream horse looks right. Find or spawn
Cr/N(palomino / buckskin / smoky black),Cr/Cr(cremello / perlino),prl/prl(classic pearl, apricot with sepia points) andCr/prl— the new combination, which should look like a double dilute, not like a single cream. The genome display writes itCrprl. - A pearl carrier is invisible.
prl/Nshould render exactly likeN/N; the display showsnprl. - Breeding still works — a bred foal gets a combined code, rolled stats and a name, and its coat matches its inherited alleles. The foal path now writes the epigenome into its record; a foal rendering as a plain black horse would mean the record never got one.
- The family tree draws ancestors’ real coats. This is the visible payoff of moving the epigenome onto the record: a non-deterministic ancestor (a bay, a grey, a splash) should show the same markings in the tree as the horse does in the world. It used to show a plausible invention derived from the record UUID.
- Save and reload. The epigenome is serialised in a new
epigenome_codefield on the record; a horse whose coat changes across a reload means that field is not round-tripping. - The seed jar still round-trips — collect from a stallion, impregnate a mare, and check the foal. The jar reads the sire’s genome off his record now rather than off an attachment.
- Suntouched / Waterborn still load and express. Both gene files
were rewritten to format 2; the log should read
loaded 2 data-driven gene(s)and20 segments. A parse error would drop them silently from the genotype. - The gene creator still exports a file the game accepts. Open
wiki/gene-creator/index.html, load an example, export, drop it in.minecraft/phc/genes/and restart. The form now asks “shows when the horse has one copy or two” and takes three founder percentages instead of a dominance dropdown and a 1-in-N field. - Pen signs. The catalogue no longer drives the corridor (item 4), so there is no tally to check — but a pen sign must still name exactly what its two horses are carrying.
The format allows any number of alleles and an outcome per combination; the creator authors a two-allele gene with one visible outcome plus a wild type, which is what its single layer list can describe. A three-allele locus like MATP, or a sabino-style two-outcome gene, is hand-edited JSON. The creator says so in its own hint text; it is not a silent limitation.
0.3 The data-model rewrite — gene priority + gene-keyed codes (2026-09-03)
Gene priority: every gene has
int priority(); all orderings derived by sorting on
(priority, key); genotype / epigenome code strings are now
gene-keyed (<geneKey>=…) and tolerant. 195
:common:test pass, runServer boots clean. (Superseded
in part by §0.2, which reran all of it.) Machinery:
Genetics model.
Confirmed 2026-09-03: wild spawns render their correct
coats (no regression from the new codeOrder() / code format),
and the right-click paper genome dump works.
Still to check:
- Breeding still produces a valid foal with a combined code and inherited epigenetics — family tree renders.
- Seed jar round-trips. Collect from a stallion, read the tooltip, impregnate a mare — the foal’s genome still matches (the jar stores the new-format code).
- The short genome display lists a spec gene. Get a horse
that carries Suntouched or Waterborn (custom spawn egg) and check the
info panel / paper dump / seed-jar tooltip name it — the old
GeneCodeDisplaybug (closed with this change) hid them.
0.4 Horse care — gated healing, bond & herds (new 2026-09-02)
First slice of horse care, all in
server/HorseCareHandler + server/BondFollowGoal.
Nothing seen in a running game. Full machinery:
horse-care.
- Gated healing. Hurt a tamed horse (let it take fall damage). Stand it next to both water and a hay bale / grass — it should tick back up ~1 health every 1.5 s with a couple of heart particles. Move it away from the water (or onto stone away from any food) → healing stops. Hand-feeding wheat should still heal it regardless of surroundings.
- Any dimension pen is a ready test bed — cauldron + hay bale — but horses there take no damage, so hurt one in the overworld.
- Bond number shows. Ride a tamed horse, open its
inventory (E): the left panel should show a
bond N waryline. Ride / stay near it for a few minutes and reopen — the number should have climbed (cap +15/MC-day). Feed it a carrot → +2 immediately. - Bond tiers. Cheat the bond up (there is no command yet — either grind it or temporarily lower the tier thresholds): at 31–60 a dismounted horse turns to face you within 10 blocks; 61–80 it walks toward you when a path exists; 81–100 it follows you around fences and walls, stopping ~3 blocks off. It should ignore you while leashed or while someone rides it.
- Herds. Park 2+ horses within 10 blocks for ten real
minutes → the information screen's Overview tab should start showing
• in a herd. Separate them for ten minutes → the flag clears. A foal in a herd should gain bond noticeably faster than one alone. Herd members near water+food should heal at +2. - Persistence. Bond and herd id survive a save/reload
(they are on a serialized attachment). Re-summoning via death does
not apply here, but
copyOnDeathis set. - Performance. Stand in the pen corridor with hundreds of (healthy) horses loaded — no tick lag. The block scan only runs for hurt horses.
1. Drop-in genes actually load — the top item
New 2026-09-02, and the whole point of the
gene creator: nothing about it has been seen
in a running game.
Baseline note: as of 2026-09-02 example.waterborn
and example.suntouched ship loaded (classpath index), so a
stock in-game genotype code is 41 segments (39 built-ins + the
two shipped spec genes). Dropping one more gene in takes it to 42. To test the
drop-in path:
- Open the creator, pick Load an example → Tobiano, and Download. Note what the preview looks like — that is the claim being checked.
- Drop
tobiano.jsonintoneoforge-26.1.2/run/phc/genes/. The folder and itsREADME.txtshould already be there from a previous launch; if not, that is itself a finding. ./gradlew :neoforge-26.1.2:runClientand read the log for[genes] loaded 3 data-driven gene(s)(Suntouched + Waterborn + Tobiano) andthe genotype code now has 34 segments. (The fixture isexample.tobiano— a different key from the built-inhorsegenetics.tobiano, so both coexist.)
What to look at:
- Wild horses carry it. 1 in 18 per allele, so a handful of spawns should include a patched one. It should also turn up on pen horses in the horse dimension, and — because it is a natural gene that paints — it joins the pool the showcase draw can force, so it will show up there more often than 1 in 18 would suggest.
- It looks like the preview did. Not texel-identical — the creator's gradient is downsampled — but the same size and shape of patches, and the same socks.
- It breeds. A foal from two carriers should show it, and the
homozygote should be visibly more patched than the heterozygote
(that is the
perDosethreshold, and it is the thing splash still gets wrong). - A foal inherits the look, not just the gene. Two horses with the same genotype should have different patches; a foal's should match the parent whose copy it took.
- Removing the file is clean. Delete it, relaunch: the code drops back to the 20-segment shipped-gene baseline. Horses saved at 21 will fail to load — expected, but confirm it fails loudly rather than corrupting anything.
- A deliberately broken file. Put a stray comma in one and confirm the game still boots, logs the error with the file name, and loads the other genes.
The creator itself, opened straight off disk (file://) as well as
served: the 3D horse should appear and orbit, clicking it should report a body
part and a body-space point, and the “show area” checkbox on a layer
should highlight exactly the texels that layer covers. If three.js is blocked
the flat sheet must still bake — that fallback is untested.
1b. Natural zebra striping (new, NOT looked at)
Codominant and 1 in 60 per allele, so shadow-striped horses (Zeb/n) are
around 3% of wild ones and a full Zeb/Zeb is a breeding project —
summon one with natural_zebra=Zeb/Zeb, or breed two shadow horses. It
shares its painter with magic zebra, so a lot of what follows verifies both.
- Is the horse its own colour, striped white? The whole claim.
Check a black (should be black and white), a
chestnut (red and white) and a palomino (gold
and white). If any of them comes out grey-and-white,
whitenis unmasking red it should not be. - Does the pattern change direction with the body? The point of
ZebraStripes. In order of how badly a one-axis field gets them wrong: rings on the legs (not vertical bars), arcs round the hip (not vertical bars across the rump), a dark dorsal stripe the side bands meet rather than cross, a dark muzzle, and a pale belly. - Is the head noise or stripes? The facial bands are at 0.60×
the barrel spacing, which is close to the floor a 2-texel-per-unit sheet can
carry. If the face reads as static rather than striping, raise
HEAD_TIGHT. - Do two striped horses look like different animals? Spacing, duty, bend and leg reach are all per-horse; the leg-reach range deliberately spans a plains zebra (plain lower legs) to a Grévy's (ringed to the hoof).
- Are the shadow stripes visible but clearly not the full thing?
One copy paints the same map at 45%. It has to be spottable in a herd — that
is the point of making the locus codominant — without being mistakable for
Zeb/Zeb. - A horse carrying both zebra loci.
natural_zebra=Zeb/Zeb magic_zebra=Mzeb/n. They draw the same map from opposite directions with independent epigenetic seeds, so the two patterns will not line up. Is that a mess or is it interesting? If it is a mess, that is an argument for magic zebra reading the natural gene's seed, and it should be recorded as a gap rather than fixed on the spot. - The foal. The barrel is 14 units instead of 22, so a foal wears fewer bands at the same spacing. Confirm it still reads as a zebra and not as a striped blob.
2. Magic zebra
New 2026-09-02. 1 in 100 per allele, so do not wait for a wild one: the
dimension’s pens force a magical gene half the time, or summon one with
magic_zebra=Mzeb/Mzeb in the code. Note the pair — it
became codominant 2026-09-11 and Mzeb/n is no longer the full
pattern. What to look at:
- Codominance — the new part, and the thing to look at first.
Put
n/n,Mzeb/nandMzeb/Mzebside by side on the same base coat. One copy should read as dusky bands a few shades down from the horse's own colour, two as hard black, and the two should not be mistakable for each other. Tuned off a rendered ladder on bay, black and chestnut, so the number (0.09 of the full subtraction) is a first guess at what reads well in game — it is the one knob here most likely to want turning. - The heterozygote is deliberately coat-dependent. It is clearly visible on a pale coat and close to invisible on a black one, which is what a shadow on a black horse looks like. Confirm that reads as intended rather than as the gene failing — if a dusky black horse looks broken rather than subtle, that is the argument for raising the number.
- Stripes read black over any coat — the
Mzeb/Mzebclaim, unchanged and byte-identical to what it always drew. Check one on a cremello / perlino and one on a dominant-white horse — that is the −200% claim, and the whole reason phase 3 is an unclamped signedint. - Repainted onto the shared body map — it no longer hangs parallel bars from the topline. Everything under §0-Z applies to this gene too, in black: vertical bands off the spine, arcs round the hip, rings on the legs, tighter bands on neck and face, a black dorsal stripe and muzzle, and an unstriped belly. The leg reach is per-horse, so two zebras should differ — one with plain lower legs, one ringed to the hoof.
- The chevron over the back, and the bands on the chest, rump and leg
fronts. These come from the
|z|slant, added precisely because those faces rendered as flat bands. They have looked right in a sample bake through two different painters now and have never been seen on the actual 3D model, which is where a body-space pattern usually goes wrong. This is the one that most needs real eyes. - Is the horse still readably its own colour? The band width is
deliberately narrower than the natural gene's (0.34–0.50 of a period against
0.42–0.60), because this one adds black and an even duty just makes
a black horse. If a magic zebra bay reads as a black horse with a few red slots,
drop
WIDTH_MINfurther.
3. Pink hair
New 2026-09-02. Recessive, so only Pihr/Pihr shows
and a wild one is about 1 in 144 — use the dimension’s pens (they force
a magical gene half the time) or a summon.
- The mane and tail read pink on a black, a
chestnut and a cremello alike, and the strand
shading survives. It should not be a flat pink slab — that is the
whole reason it reads
ColorView.visiblefirst. - On a dominant-white horse the hair is pink rather than white.
- A foal gets a pink tail only — the foal mesh has no MANE part. Worth confirming that looks acceptable rather than broken.
- A horse carrying both magical genes: the zebra stripes should
cut across the pink mane, not the other way round. That is
magicalOrder().
4. The horse dimension is random pens now (new 2026-09-04)
The gallery is gone. Each pen rolls its own
ShowcaseGenotypes.random draw instead of holding a catalogue entry,
and the corridor is a fixed 2,000 pens (about 7,000 blocks)
rather than a length derived from the genotype space. This replaces the old items
4, 6 and 7 — do not go looking for catalogue order.
Enter with F6 (or a hay portal) and walk 20–30 pens:
- No plain horses. Every pen shows at least one coat gene beyond extension and agouti — a dilution, a marking, a grey, something. A corridor of ordinary bays and chestnuts means the floor is not working. Note the one honest gap: the floor guarantees a gene is expressing, not that it is perceptible — mushroom on a black horse is a real expression that looks like nothing. If pens read plain often enough to be annoying, that is the cause, and it is worth reporting.
- Roughly half the pens show a magical gene (a pink mane, zebra stripes, a shipped Suntouched or Waterborn). Not exactly half by eye — it is a coin per pen — but a corridor with none, or with one in every pen, is a bug.
- The pen sign still stands on the road to the right of the gate as you face the pen (the two sides of the road mirror), is readable from both faces, is waxed (right-click does not open the edit screen), and matches the two horses in that pen. Line 0 is now just the pen number.
- Busy signs still overflow their last line. Known and
deliberate —
wrapwould rather run off the sign than drop a gene. Now that the labels are random rather than exhaustive they should overflow far less often; if it still reads badly, that is worth a decision. - The entrance sign three blocks in front of the return portal
now reads
Horse Pens / 2,000 pens / random genome / mare + stallion— no catalogue tally, because there is no catalogue to tally. - The pair still differs. Both horses match the sign and differ only where a non-deterministic gene (bay points, grey dapples, splash) makes them differ — they share a genotype and not an epigenome.
- The corridor ends in a wall after pen 2,000, about 7,000 blocks out. Reachable by flying, unlike the old one.
- Pen amenities: the sunk water cauldron and hay bale still sit flush with the grass, and the horses stay penned.
Leave and re-enter — this is the item that changed shape. Blocks are still left standing on teardown, but the contents are random now, so:
- The new corridor is a different set of horses from the last visit — every pen you walk past is rebuilt, sign and horses together.
- Walk further than last time: no stale sign, no doubled horses, no pen
whose horses disagree with its sign.
buildPenclears untamed leftovers before it stocks, so a previous visit’s animals must not survive. - Walk less far than last time, then leave: nothing should be left behind in the far end. The teardown box now covers the whole corridor, not just the part built this visit.
- Leaving is still instant.
5. The three-phase pipeline refactor — lowest priority
CoatPipelineGoldenTest proves 20 genotypes × 3 seeds ×
adult/foal compose byte-identically to the pre-refactor code, so no coat is
expected to have moved. The one thing the test cannot cover is that it
runs against a synthetic 16×16 gradient and a flat template, not the real
500×500 redblackgradient.png and horse_white*.png.
So: on the next runClient for any other reason, glance at a
magic-zebra horse (black stripes on any base, dominant white
included) and at any dominant-white horse. Nothing else needs
looking at. (This item used to name the Test gene, which
was removed 2026-09-05.)
6. The custom spawn egg, rebuilt (new 2026-09-04)
The editor is a different screen now: every registered gene down the left in alphabetical order by its display name, a live 3D horse in the middle, and age / sex / reroll / copy / paste / reset / spawn down the right. Open it by right-clicking with the custom horse spawn egg.
- The names are the real ones. The list reads
“ACAN”, “Agouti”, “B4GALT7”,
“Champagne”, “EDNRB (frame overo)”, “KIT (white
spotting)”… in alphabetical order — not
horsegenetics.ednrb, and not registry order. Long names are scaled down to fit; check they are still legible. - Clicking a gene adds it. A gene not on the horse is a plain
name that highlights under the cursor; click the row and it gains two allele
buttons and an
x. Nothing should show allele buttons until you add it — a screen ofN/Nbuttons is the thing this replaced. Scroll the list (mouse wheel over the left column) and confirm the last gene is reachable at your window size. - It lands homozygous for the allele that does something
— Champagne as
Ch/Ch, Grey asG/G, notN/N. Two to check specifically: KIT, whose first fourWhomozygotes cannot occur, must land on the first one that can (never a nonviable pair); and MET, whosemet/metcannot occur at all, must land heterozygous. - The
xtakes a gene back off and it returns to a plain name. - The row says what it expresses. An added gene shows its
outcome name under it (“Bay”, “Silver”,
“Dominant white”) and the name turns green; cycle it back to
baseline and it reads
no effect. That is the expression prose finally being read by something. - The preview redraws as you edit and switches between the adult and foal model with the Age button. Controls changed 2026-09-05: the horse no longer follows the cursor — click-drag over the preview to orbit it (yaw + pitch, pitch clamped ±80°) and scroll-wheel over the preview to zoom (0.3–4×, on top of the size-locus scaling). The horse is always mid-stride now — legs swinging, tail animating.
- Particle emitters preview (new 2026-09-05). Add a
particlegene (or spawn Waterborn / Suntouched) and a cloud of coloured motes should drift round the horse in the emitter's colour — low round the hooves for a feet anchor, mid-body forbody/spine. It is a GUI stand-in, not a real particle (the emitter translator is server-side and the preview horse never ticks): check the colour is right (the particle locus draws it from the epigenome — a Rnd epigen. randomize should change it) and that it does not leak outside the preview panel or tank the frame rate. It does not track the model when you orbit/zoom — it stays a band round the panel centre. - Rnd epigen. (the last entry in the Randomize menu)
changes the preview without changing the genotype — watch bay
leg heights, grey dapples or a splash edge move. The
epigenetics #line under the list changes with it, and a locked row must not move at all. - The spawned horse is the previewed horse. This is the point of the change: set up a striking non-deterministic coat, note the epigenetics number, spawn, and check the horse in the world looks identical to the preview. The server used to re-roll it.
- Copy code puts the genotype code on the clipboard; Paste code reads one back and the whole list (and the sex button) moves to match — and only the loci that are actually off baseline come back as added rows, not all thirty. Round-trip one: copy, Clear genes, paste, confirm you are back where you were.
- Creative only, server-checked. In survival, Spawn must do nothing but print “the custom spawn egg is a creative-mode tool”. The egg is no longer consumed in survival, because it no longer works there.
- Many-allele genes use a dropdown (new 2026-09-05). A gene with more than 3 alleles (particle 41, KIT 8, ACAN 5, MITF 4) — clicking either allele button opens a scrollable list (8 visible, wheel to scroll, thin scrollbar) anchored at the button; click a token to set it, click anywhere else to dismiss. Genes with 3 or fewer alleles still cycle on click. Check the particle list is usable (was 41 clicks) and that the panel clamps on-screen for a gene low in the list.
- Randomize button (new 2026-09-05, right column under
Breed). With Breed: Feral Mixed it rolls a fully random
genome (
Genome.random); with a breed selected it rolls a fresh founder of that breed (BreedFounder.roll) so the alleles stay inside the breed's pools. The chosen Mare/Stallion is kept. Loci left at baseline don't appear as added rows. The epigenetics number changes too.
7. The old spawn-egg follow-ups, re-check after the rebuild
Both 2026-09-02 fixes were in the code the rebuild replaced, so confirm they still
hold: the screen’s backdrop must not draw over its own buttons (widgets
render during super.extractRenderState), and nothing may run
off the bottom of a short window.
8. Foals — only spot-checked, needs a real pass
Every treatment should apply on HdBabyHorseModel: a bay foal with
black points and leg black, a splash foal with white socks, a champagne foal gold,
a grey foal born its base colour and greying when grown. The baby head and
neck geometry is a rest-pose AABB approximation — watch the face and
neck for odd dark patches or misplaced marks.
9. Per-allele epigenetics + the grey rework
New 2026-09-01, not seen in-game.
- Grey adults are grey, and dappled — a neutral grey with visible rounded dapples, not the old flat near-white. Sample bakes put the dapple field at a 21–29% lightness modulation on the mid greys (5% on a nearly-white one, where there is no pigment left to vary).
- Greys differ from each other. Stand two adjacent grey pens side by side: one should read dark steel, another mid dapple, another nearly white, with different dapple sizes.
- The dapple field crosses part seams with no join at the shoulder, haunch or neck — that is what body-space sampling is for.
- Young greys keep darker points (mane, tail, lower legs) — the point-retention knob is strongest on the least-greyed horses.
- A grey foal is still born its base colour and greys once grown (clock it up in the horse dimension).
- Bay leg black really varies now. Wild bays should run from low
socks to seal, and the four legs of one horse should not stop
level. Bay’s extent is now uniform, not the old
f*fproduct that clustered everything at the bottom. - A foal looks like its parent, not like a re-roll. Breed a
seal-ish bay mare to a non-bay stallion; a foal that got her
Ashould carry her point heights. Breed the same pair repeatedly: foals that inherited the same copy should be identical in that respect (no variation is deliberate for now). Spl/SplvsSpl/splepigenetics. On a homozygote the higher-priority copy’s seed is used. There is no way to see the number in-game yet, so the check is just that a homozygote renders stably — same markings every session.
10. The epigenome persists across save → reload
Bay leg heights, grey dapples and splash markings identical after a reload.
The attachment format changed (epigenetic_seed: long →
epigenome: String), so an existing dev save’s horses cannot
read their old coat attachment — they will re-found epigenetics, or the
attachment errors outright. That is the no-back-compat rule working as
intended.
11. Everything else
| Item | How to check |
|---|---|
breedNth foal names past foal 1 | Breed one pair 7+ times: foal 1 = parent combo, foal 2 = the other combo, foals 3–6 = one parent name half + a random word, foal 7+ = fully random, no repeats. HorseNames is unit-tested; the live offspringCount(dam, sire) link is unproven. |
FamilyTreeScreen scroll mode | The default shrink-to-fit chart is confirmed good; the other path is not. Flip familyTree.scrollBar true in phc/client.toml and check the wheel and the right-edge thumb. |
| Stats surfaces | Foal speed/health landing on the entity’s attributes; the inventory-panel green/amber/red tint vs parentStats; the paper dump’s vs parents line. |
| Compact gene code | GeneCodeDisplay.shortForm on the surfaces not specifically eyeballed: the paper dump’s genetic code: line and the mounted info panel’s word-wrapped block. |
| Water riding feel | HorseWaterRidingHandler — the speed cap (0.09 b/t) and the submerged lift are a first guess. |
| Debug coat-gen chat line | Should be quiet in a release build. It fires correctly in dev; the !FMLEnvironment.isProduction() gate is unproven. |
12. Dev test worlds delete themselves
New 2026-09-01, client/DebugTestWorldCleanup. Click Spawn Test
Horse World on the title screen, play a bit, quit Minecraft normally
(Save and Quit → Quit Game). Check:
neoforge-26.1.2/run/saves/has notest_horse_*folder left, and the log has aDeleted test horse world test_horse_… (on shutdown)line.- The hand-made worlds next to it are untouched — the
sweep matches
test_horse_+ digits only. - Spawn two test worlds in one session (button, quit to title, button again), quit — both are gone.
- Kill the client mid-world (
taskkill, or Alt+F4 in a hang) so shutdown never runs, then relaunch: the leftover is cleared at startup with a(left over from a previous run)log line, before the world list is shown.
13. Gene effects — the Waterborn & Suntouched genes
New 2026-09-02, and the proof that the data-driven
effects pipeline works in a running game. Waterborn and Suntouched
ship loaded (classpath index in the NeoForge module) — boot log
shows [genes] loaded 2 data-driven gene(s) / 13 segments
with no config drop. Gene pages: Waterborn,
Suntouched. Fastest test horse is the
custom horse spawn egg (item 14: add the gene, spawn).
Confirmed in-game 2026-09-02:
- The neon-blue streaks in the mane and tail render.
- The blue particle trail works.
Still to check:
- Streaks on hard cases. Confirm they still read on a
cremello and on a dominant-white horse (the
TOWARD+opacity: 100claim), and that a foal gets them on the tail only (noMANEpart on the foal mesh). - Walks on water. A grown Waterborn horse in water should ride
at the surface and not sink; a foal should not (the
when: adultgate). This is an approximation — buoyancy, not a solid plane — so watch for bobbing, getting stuck at the edge, or the rider's head going under. - Mares milk for water. Right-click a tamed mare with an empty bucket → it becomes a water bucket, no mount happens, and a second try within ~2 minutes does nothing. A stallion, or an untamed mare, should just mount as normal.
- The log line
effect 'attribute' ... defined but not translatedshould not appear for Waterborn (it has none). - Streak pattern varies per horse and a foal inherits its
parent's (the
stripeSeed/stripeSpacingknobs).
Suntouched — the glow verb. Confirmed in-game
2026-09-02: the emissive gold mane + tail render and look good, the
gold-dust emitter shows, and the horse lights the area around it
(the trailing minecraft:light block).
Still to check:
- The light cleans up. Kill the horse, or walk it far enough
to unload — the
minecraft:lightblock must disappear, not linger. In the horse dimension there should be no light blocks at all (it is skipped there on purpose). - The light follows and lags. Gallop and watch the lit patch lag or stick a block behind — it is a trailing block, not a smooth source. Confirm it can't light a spot already filled by a block.
- Foal. A Suntouched foal should glow too, tail only (no mane part on the foal mesh), and still cast light.
- Hard base coats. The emissive mane should still read over a
cremello and a dominant-white horse
(
opacity: 100on the coat layer). - Deterministic. Two Suntouched horses of the same base coat should look identical (no knobs).
14. Custom horse spawn egg — what survived the rebuild
The screen was rebuilt on 2026-09-04 (item 6 above is the new surface). Three things from the 2026-09-02 pass are still worth a look because the rebuild kept the behaviour but not the code:
- The spawned horse renders the picked coat, not a random one, and its info panel / paper dump shows that genotype. Foal/Adult and Mare/Stallion match the toggles. Spawned horses are persistent, and two custom horses breed normally.
- Allele buttons cycle and wrap on a multi-allele gene — MATP has three, KIT eight.
- A drop-in gene appears in the list. Waterborn and Suntouched ship loaded, so they should be in the list like any other gene, and both are magical genes with real effects to check on the spawned horse.
Carried over, differently: the modal “+ Add gene” picker is gone, but adding is not — the list itself is the picker now, and the “a new row lands on the allele that does something” rule is still there (item 6). Retired outright: the survival egg-consumption path, since the spawn is creative-only.
15. The gameplay-layer items
Built 2026-09-02: 17 items for the gameplay layer. Most are
still behaviourless (item + recipe + creative tab only); the two seed
jars have behaviour — see §16. Registered in
item/ModItems; one Horse Genetics creative tab
(item/ModCreativeTabs) holds all of them, and the custom horse spawn
egg still also shows in the vanilla Spawn Eggs tab. Every item except the two
stall signs (which borrow the vanilla oak-sign icon) has owner-supplied art.
- Creative tab & names. Open creative, find the
Horse Genetics tab (just before Spawn Eggs); confirm all 20 items
show (spawn egg + 19), each with a readable name and its own icon — not
an
item.horsegenetics.…lang key or a missing-texture checkerboard. Tickets (4) deliberately share one icon; whistles (3) share one; the two stall signs share the oak-sign icon. - Hair chain.
horse_hair(individual) andhorse_hair_bundleare distinct items with distinct art; 4 hair craft a bundle and a bundle uncrafts to 4 hair. - Debug world. The “Spawn Test Horse World” title-screen button puts the custom horse spawn egg on hotbar slot 0 (tools hay/carrot/stick/clock/paper/lead shifted to 1–6) and one of every new item in the main inventory (slots 9+). Since 2026-09-07 it also drops you in the middle of the nearest plains village - see §0-AC.
- Recipes. All shapeless, each takes at least one modded item.
Spot-check in a crafting table:
known_gene_splice_carrot= golden carrot + PLACEHOLDER GENE BOOK + horse hair + gold ingotempty_seed_jar= glass bottle + horse hairblank_ticket→basic_ticket→bound_ticket(+ ender pearl) →interdimensional_ticket(+ ender eye + blaze powder)basic_whistle(horse hair + iron nugget + stick) →golden_whistle(+ gold ingot) →echo_whistle(+ echo shard)- the four breeding carrots = golden carrot + horse hair + one reagent (fermented spider eye / gunpowder / quartz / glowstone dust)
horse_hairandstallion_seed_jarhave no recipe (the first is sheared — not built — the second comes from a stallion, §16); both are in the debug inventory. - Inert, do not expect anything on use: shearing for hair, any carrot effect, and the tickets (intended to teleport a horse back to its stall — stalls now exist, §18, but the teleport isn’t wired). The whistles (§17) and stall signs (§18) work.
16. Stallion seed jar — collection + impregnation (first slice)
Built 2026-09-02 (server/StallionSeedJarHandler, the
horsegenetics:stored_genome data component,
common/genetics/GenomeSample, and the shared
HorseBreedingHandler.applyBredFoal). First test 2026-09-02 found the
held jar never changed in creative (result went to another slot); fixed —
the jar now transforms in the player’s hand, creative
included. Owner also asked that the horse be in breeding mode first
(fed a carrot / apple — isInLove()); that gate is now on both
ends and the love state is consumed by the op. Partly owner-confirmed
2026-09-02 (collection + tooltip work; genome-string display bug is a
separate open issue, the data itself is right).
Still to check:
- Breeding-mode gate. Right-click a stallion that has not been fed → chat “… must be in breeding mode - feed it first.”, jar unchanged, no mount. Feed it a golden carrot (works in creative), then collect → succeeds, and the stallion is no longer in love (hearts stop) afterward.
- Collect. Right-click a tamed adult stallion in
breeding mode (info panel says “Stallion”) with an
empty_seed_jar. Expect: the jar in hand becomes astallion_seed_jar(stack >1: one spent, filled one to the inventory), a chat line “Collected a seed sample from …”, and no mount. Hover the filled jar: tooltip shows “Sire: <name>” and a short genotype string. - Wrong target. Empty jar on a mare, or a filled jar on a stallion / foal → a chat line naming the horse and its recorded sex, no mount, jar unchanged.
- Impregnate. Right-click a tamed adult mare in breeding mode (not on breeding cooldown) with the filled jar. Expect: heart particles on the mare, a foal spawns at the mare, the jar is consumed, the mare drops out of love and goes on the normal post-breeding cooldown, and a chat line “<foal> was born.”
- The foal is a real bred horse. Its coat renders (adult art on an adult, correct once grown), its info panel / paper dump shows a genotype combined from the mare and the jar’s stored sire, its name mixes both parents, generation = 1 + max(parents), and stats roll between them. It is tamed to the mare’s owner.
- Determinism. Same mare + same jar should not be testable twice (jar is consumed) — but a foal from the jar vs. a foal from the live stallion, same mare, should look like siblings, not clones.
- Persistence. A filled jar keeps its data across a save/reload and when dropped on the ground / put in a chest (it is a real persistent + networked component).
Explicitly not built (don’t flag as bugs): the breeding-mode gate is vanilla love, not one of this mod’s breeding carrots (they still do nothing); no 30-second timed window beyond however long love lasts; no gestation delay (foal is immediate); no carrot effects on the jar. Family tree may not draw the sire node (the jar stores the donor UUID but the stallion isn’t necessarily loaded).
17. Whistles — recall your tamed horses
Built 2026-09-02 (item/WhistleItem). Not play-tested.
Right-click anywhere (air, ground, a block) holding a whistle: every
tamed horse you own within range, in the same dimension, not
being ridden, is teleported to a spot beside you (spread on a grid). Ranges:
basic 16, golden 32, echo 64
blocks. ~3-second use cooldown.
- Tame 2–3 horses, walk ~10 blocks away, right-click the basic whistle → they appear next to you, not stacked inside each other, on the ground (not buried / floating); a chime plays; chat says “Whistled N horse(s) to you.”
- A horse you don’t own, or an untamed one, or one being ridden, is not moved. A horse already within 3 blocks is left alone.
- Stand >16 but <32 blocks from a horse: basic whistle says “No tamed horses…”, golden pulls it in.
- A leashed horse is unleashed and comes. A horse you are riding is not yanked out from under you.
- Cross-dimension is out of scope — a horse in another dimension is never recalled.
18. Stall signs — bind a horse, define its stall
Built 2026-09-02 (item/StallSignItem, server/StallSignHandler,
server/StallDetector, server/StallDebug,
data/StallData + data/StallRecord + data/BoundHorse).
Not play-tested. Both stall-sign items are in the
Horse Genetics creative tab and the debug-world inventory; they borrow the
vanilla oak-sign icon for now.
- Bind. Right-click a horse with a Stall Sign (blank). Expect: the sign in hand becomes a Bound Stall Sign (stack >1: one consumed, bound one to the inventory), chat “Stall sign bound to <name>.”, no mount. Hover it: tooltip reads “Bound to: <name>”.
- Build a stall & place the sign. Wall in a small area (a 1–3 block-tall box, fully enclosed, ≤512 open blocks — leave no gaps). Right-click the outside face of one wall block with the bound sign. Expect: a real oak wall sign appears there reading “Stall / <name>”, a green particle box flashes around the detected interior, and chat prints “[stall] <name> @ x,y,z WxHxD (N blocks)”. The sign item is consumed (not in creative).
- Not enclosed. Try it with a hole in the wall / open top beyond one layer up → chat “No enclosed area behind that block…”, no sign placed, item not consumed.
- Wrong face. Click the top/bottom of a block → “Place the stall sign on a vertical wall face.”
- Debug overlay. Press F7 anywhere: every stall within ~96 blocks in this dimension re-flashes its particle box and prints its summary line. (Dev-only keybind; nothing in a production build.)
- Release. Break the placed oak wall sign → chat “Stall released - its sign was broken.” and F7 no longer shows it.
- Re-bind / move. Bind a new sign to the same horse and place it on a different stall → the old stall record is replaced (one stall per horse). Persists across a save/reload.
Not built (don’t flag): teleport-to-stall / auto-return (that is the tickets); a persistent in-world wireframe (the overlay is a one-shot particle flash); any cleanup other than breaking the exact sign block (rebuild the wall elsewhere and the record goes stale).
19. The dilution and non-KIT pattern genes
Built 2026-09-02 — dun,
silver dapple,
mushroom, roan,
tobiano and frame. Hand-written Genes in
common/genetics/genes/. All are rare in the wild
(1/24–1/60 per allele); summon them with
dun=D/d2, silver=Z/z, mushroom=Mu/Mu,
roan=Rn/rn, tobiano=To/to, ednrb=O/N.
Sabino has moved to the KIT locus and frame to
EDNRB — both are checked in
§0, the white-pattern loci, not here. Sample bakes look
right; nothing seen on the 3D model. What to check:
- Dun — body lightens (grullo on black, tan on bay, apricot
on chestnut) and a dark dorsal stripe runs nose → tail
with faint horizontal leg bars on the cannons. The markings
must read dark against the diluted body, not vanish. (Grullo was
warm-brown in the first bake;
keepRednow scales to 0 on a black base so it should land a proper mouse-grey.) The third allele is a separate item — see §0. - Silver on a black → chocolate body, near-flaxen mane/tail; on a bay → "silver bay" (red body untouched, points + mane lightened). On a chestnut it must be invisible. No dapples yet — don't flag that.
- Mushroom only shows
Mu/Muand only on a chestnut → flat sepia/khaki. On black/bay it's a carrier (near-invisible). - Roan — salt-and-pepper white flecks through the barrel, densest at the hindquarters and feathering out forward so there is no hard line at the face; head, mane, tail and lower legs solid. Blue/red/bay roan by base. Watch for stray gold specks at fleck edges (the LUT diagonal) - a few are expected.
- Tobiano — large crisp-edged white patches (hard binary, no soft fringe) that cross the topline, white legs, coloured head. Non-deterministic: two tobianos differ. Check the patches actually run over the spine and that both sides of the horse are not mirror-identical.
- Frame overo (now
ednrb=O/N) — ragged white on the sides of the neck/barrel that stops short of the spine, plus a broad white face; legs stay coloured. This is the exact inverse of tobiano — check the two side by side.O/Ois a separate item in §0. - Eyes survive a topline-crossing tobiano
(
redrawEyesruns last, so they should). - Foals — all of them on a foal; the foal mesh has no MANE/MUZZLE so dorsal-stripe-up-the-face and flaxen-mane are coarse there.
- Stacking — silver bay dun, a roan tobiano, a cream plus
kit=SB1/N: nothing should throw or produce a flat-white horse.