Gameplay / world

Generated stables

Buildings that generate in the world with horses already in them — horses a player could not have bred yet, from breeds and gene combinations the wild population does not hand out. Three ship; each is somebody else’s build, and the attributions below are the point of this page as much as the mechanics are. Built 2026-09-07, not play-tested — checklist in verification §0-AK.

Attribution is not optional here

Every building on this page was made by somebody else and downloaded from Planet Minecraft. This mod is CC BY‑NC 4.0 and asks its own forks to credit it; shipping other people’s work without doing the same would be indefensible. A new stable is not finished until its author and source are on this page, and the bake script says so too.

Unresolved: Planet Minecraft submissions carry no uniform licence, and the terms for these three have not been read one by one. Before this mod is distributed anywhere, that has to be checked per build, and permission asked where it is not clear. See gap 80.

The three

StableAuthorSourceSize
Horse Stable
horsegenetics:horse_stable
Seuchendoktor planetminecraft.com/project/horse-stable-4536108 28 × 10 × 32
Stables
horsegenetics:stables
Alpha_One_Seventeen planetminecraft.com/project/stables-3837665 38 × 23 × 49
TM U Stable
horsegenetics:tm_u_stable
Tyiarrah planetminecraft.com/project/tm-u-stable 86 × 32 × 72

Who lives in each

Horse Stable — the good, plain horses

Always seven, and the only stable with a field: four outside under the sky, three in the stalls. Every horse is high-rarity and entirely natural — two forced loci of rare tier or better, and no magical gene at all. It is the stable a player is meant to find first: nothing about it is impossible, and everything about it took somebody a long time to breed.

Stables — the Friesian magic line

Two to twelve horses, all in stalls, all Friesian. Every one carries at least one homozygous magical trait, and a ladder of extras: a 10% chance of a second, 5% of a third, halving each time, up to ten extra. So most of them have exactly one, a handful have two, and somewhere out there is a horse with eleven.

A stable that names a magic count owns the magic

“At least one homozygous magic trait” is a statement about the horse, not about what this stable adds to whatever its breed already rolled. So the magical loci are cleared first and exactly the rolled number put back. Without that every horse had its breed’s own magic plus the guarantee, and the ladder described nothing anybody could observe — which is how the unit test found it.

The four body-stat loci (size, magic speed, health, jump) are exempt from all of this, everywhere. They are magical genes and they are not magic: they are how BreedFounder hits a breed’s speed and height bands, and clearing them would quietly delete the breed’s character.

TM U Stable — the show yard

Three to fifteen horses, all in stalls, drawn from the white-marking breeds: American Paint, Appaloosa, Knabstrupper, Gypsy Vanner, Clydesdale, Shire, Mustang, Kiger Mustang, Shetland, Icelandic, Marwari, Falabella, American Miniature. No magical gene that paints — a horse here may still glow or heal, but it may not be a colour no real horse could be, because the whole point of the yard is the markings.

What a stable may never do

A player did not choose to open this box

They walked past a building. So every locus a stable forces is drawn from the same pool the random splice carrots use — SpliceSafety — and cannot be a lethal or a heart cost. That is a unit test, not a comment.

An impairing condition is a different matter and is allowed: that is the breed’s own genetics talking, exactly as it would on a wild horse of the same breed. A stable is not a promise of a healthy animal. A building full of dying foals would not be a surprise, it would be a bug.

Adding one: two files and no Java

That is the whole design, and it is why the generation half is vanilla’s and the horses half is this mod’s, joined only by a structure id. A pack that ships only the worldgen gets an empty building; one that ships only the stable file is ignored until a structure by that id exists. Both failures are quiet and neither breaks a world.

1. The building

A Minecraft structure NBT at data/<ns>/structure/<id>.nbt, plus the three ordinary vanilla worldgen files that place it — worldgen/structure/<id>.json, worldgen/structure_set/<id>.json and worldgen/template_pool/<id>.json. Copy this mod’s and change the ids; the structures here are minecraft:jigsaw with a single-element start pool, terrain_adaptation: beard_thin, and a random_spread placement.

A WorldEdit schematic is not a structure

None of the three sources was usable as shipped. Two are Sponge Schematic v2 and one is a legacy MCEdit .schematic with numeric 1.12 block ids and no block names in it at all. tools/stables/bake-stables.py converts both to structure NBT, and the trick that makes it cheap is that the output keeps DataVersion 1976 (1.13.2): the game runs every structure it loads through the DataFixer against its own version, so grass_path becoming dirt_path and every other rename since is done by Minecraft, correctly, for nothing. The legacy id table only has to reach 1.13.

The bake also drops block entities and entities, and substitutes blocks from mods this one does not depend on — TM U Stable carries a placeableitems:saddle_stand_block, and a structure naming a block that does not exist does not degrade, it fails to load.

2. The horses

One file at data/<ns>/horsegenetics/stable/<id>.json. Everything but structure has a default, so the shortest useful one is two lines.

{
  "structure": "horsegenetics:horse_stable",
  "name": "Horse Stable",
  "min_horses": 7,
  "max_horses": 7,
  "field": 4,
  "breeds": ["friesian"],
  "magic": "none",
  "rare_natural_genes": 2,
  "rare_tier": "rare",
  "min_magic": 1,
  "max_magic": 11,
  "extra_magic_chance": 0.10,
  "extra_magic_falloff": 0.5
}
FieldDefaultWhat it does
structureThe structure id this rule is about. The only required field.
name"Stable"For logs and this page. Not shown in game yet.
min_horses / max_horses1Inclusive; rolled per building.
field0How many stand outside under the sky. The rest go in stalls. A target, not a promise — see below.
breedsemptyDraw uniformly from these breed ids. Empty means the feral mix. A named breed that has switched stable off in its own file is skipped — a stable definition is written once by whoever built the building, and the breed’s file is the later and more specific word on where it may turn up.
magic"allowed"none clears every magical locus; no_coat clears only the ones that paint; allowed leaves the breed’s own draw alone.
rare_natural_genes / rare_tier0 / "rare"How many natural loci at or above that rarity tier to force into a state that actually shows (homozygous, so a recessive is not wasted).
min_magic / max_magic0The homozygous magic guarantee and its cap. Naming either makes the stable own the horse’s magic entirely.
extra_magic_chance / extra_magic_falloff0.10 / 0.5The ladder. Each extra is conditional on the one before it, and the chance is multiplied by the falloff each rung.

How it finds the stalls

A stall is not a thing a structure NBT can say, and requiring a modder to bake data markers into somebody else’s schematic would make “drop in an NBT” untrue. So server/StablePopulator reads the placed blocks:

Two sides rather than three, deliberately: a stall’s open side is its gate and the one opposite is often open to the aisle, so three would find only boxes, and a box is not a stall. One spot per column, so a horse on a stall floor and another on its roof are not two stalls.

It is a heuristic and it is meant to be. It costs a modder nothing, it degrades to “put them in the field” rather than to “put them in a wall”, and a stable that asks for three stalled horses in a building with two stalls gets two and the third outside. The owner’s phrasing for the first stable was “3 in the stalls (if possible)”, which is exactly this contract.

When the horses arrive

There is no “a structure finished generating” event. What there is: a chunk load, and a StructureStart that knows the piece’s whole bounding box. So a stable is queued when a loading chunk reports a start for it, and populated 40 ticks later — by which time the neighbouring chunks the piece spans have had their own feature stage and the stalls actually exist. It waits again if any of them is still unloaded, because a horse spawned into an unloaded chunk is a horse that never existed.

Do not add a position check here

There was one, and it emptied three stables in four (gap 136). It compared the bounding box’s minimum corner against the chunk being loaded, meaning to say “only the chunk that owns this start” — but a jigsaw start piece is placed at its chunk’s minimum block corner and then rotated, and the rotation happens about BlockPos.ZERO. Three of the four rotations carry the box into the previous chunk in x, z or both, so three quarters of stables never matched and were never queued at all.

No check is needed: getAllStarts() already returns only the starts belonging to that chunk, and StablePopulationData.claim() is what makes population happen once per world. The queue dedupes on the same (structure, corner) key claim() uses, so the two cannot disagree about what “the same stable” means.

A stable writes two log lines, and which one is missing says which half broke: [Stables] queued … when it is noticed, and [Stables] filled … with N horse(s) (X stall, Y field found) when it is populated. Neither is gated by debug.announce — they are once per stable per world, and they are what a bug report needs.

A per-level StablePopulationData remembers which stables have been filled, keyed by structure id and bounding-box corner. Without it a stable would gain another seven horses every time a player walked back to it — the classic failure of this whole class of hook, and the kind that looks like a feature for two days and then is a paddock with three hundred horses in it.

The draw is seeded off the world seed, the corner and the structure id, so the same stable in the same world is the same stable however many times its chunk is reloaded, and a bug report naming a location can be reproduced. Every horse is setPersistenceRequired(): one a player walked half a world to find must not despawn because they left to fetch a saddle.

Turning the commentary on

This mod says what it is doing — a cowboy founding, a villager taking the horseman job, a stable being filled — in chat and in the log, because most of it happens where nobody is looking. That is a development tool, so debug.announce in the server config is on in a development run and off in a normal install. It shipped hard-coded on once, and players got [Cowboy] and [Horseman] lines in their chat (gap 137).

Set it to true in a normal install when you are chasing something and want a paste-able log. The line [Debug] chat+log diagnostics enabled=… at startup says which way the switch went, on purpose: a gate you cannot read is how “no debug line ever printed” once became unanswerable.

How often they generate

StableSpacingSeparationBiomes
Horse Stable4816#horsegenetics:has_stable — plains, sunflower plains, meadow, savanna and plateau, forest, flower forest, birch forest, taiga, snowy plains
Stables6424
TM U Stable7228

In chunks, and rarer than a village (32 / 8) by design: each one is a handful of horses a player could not have bred yet, and the smallest, plainest building is the most common of the three. All three share one biome tag, which is open, grassy, buildable ground — a stable on a mountainside is a stable half-buried in a mountainside.

None of these numbers has been played. Spacing and separation are the first thing to turn if stables feel too common or impossible to find, and they are a datapack edit rather than a code change.